docker--文件构建镜像

【1】通过文件构建镜像

以下是我们比较推荐的保存镜像的方式,也是我们工作中比较常用的方式,以Dockerfile文件的方式

1.创建一个Dockerfile

注意:一定要创建一个新的目录 因为在构建镜像的时候,会默认把dockerfile所在的目录中的所有目录发送给docker引擎,举个例子 如果你把dockerfile放在/目录下 那么这个过程会变得非常的缓慢

1):mkdir /mnt/docker
在这里插入图片描述
vim /mnt/docker/dockerfile

FROM busybox #以busybox 基础镜像为模板 
RUN echo testfile > file1 #在新镜像中要执行的哪些动作 
RUN echo testfile > file2

在这里插入图片描述
2):用dockerfile文件来构建镜像

 docker build -t busyboxtest:v1  .

##busyboxtest为镜像名称,"."代表当前目录
docker images ##查看到创建的镜像
在这里插入图片描述
docker history busyboxtest:v1
在这里插入图片描述

 docker run -it busyboxtest:v1   ##以busyboxtest创建容器查看
 / # cat file1
 / # cat file2 

docker ps -a ##创建容器不给容器起名字的时候,会自动给起名字
在这里插入图片描述
在这里插入图片描述
再次更改dockerfile

缓存特性
再次更改dockerfile 注意:不要随便加空格(要使用缓存之前内容不能随便更改)
vim /mnt/docker/dockerfile

 FROM busybox
 RUN echo testfile > file1
 RUN echo testfile > file2 
 RUN echo testfile > file3

在这里插入图片描述
docker build -t busyboxtest:v2 .
在这里插入图片描述
注意此时的版本不能和之前镜像存在的版本重和

docker  run -it busyboxtest:v2
/ # cat file1 
/ # cat file3

在这里插入图片描述
docker history busyboxtest:v1
docker history busyboxtest:v2
在这里插入图片描述
对比来看:

v2和v3 有几层是一样的 每一个RUN就会构建一层镜像
而且我们可以看到 每一层的操作
再次说明同一个的镜像层之间是共享的
本质:dockerfile中的每一层其实就是执行了一个docker commit

如果我们希望在构建镜像时不使用缓存,可以在docker build命令中加上 --no-cache参数
#dockerfile中每一个指令都会创建一个镜像层,上层是依赖于下层的,无论什么时候,只要某一层发生变化,其上面所有层的缓存都会失败

删除之前做的容器
docker rm -f

在这里插入图片描述
【2】dockerfile的详解

便于我们书写更成熟的dockerfile文件
dockerfile常用指令

FROM:指定base镜像,如果本地不存在会从远程仓库下载(虚拟机要配置上网) 
	MAINTAINER:设置镜像的作者,比如用户邮箱等 (不是必须的) 	
COPY:把文件从buile context复制到镜像 	
支持两种形式:COPY src dest 和 COPY  ["src","dest"] 	
src必须指定build context中的文件或目录 	  

1:vim /mnt/docker/dockerfile

 FROM busybox 
 COPY testfile /tmp   ##将testfile文件复制到/tmp下
 COPY ["hello","/tmp"] ##将hello文件复制到/tmp下

在这里插入图片描述
vim testfile
test

vim hello
hello
在这里插入图片描述
docker build -t test:v4 .
在这里插入图片描述
docker images
docker history test:v4 docker
在这里插入图片描述

docker run -it --name vm1 test:v4 
 / # ls 
 / # cd /tmp/  
 /tmp # cat hello 
 /tmp # cat testfile    	 
# 建议:不用的镜像和容器 要及时删除

在这里插入图片描述
在这里插入图片描述
2: ADD:用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以下载URL并拷贝到镜像

eg:ADD html.tar /var/www
ADD http://ip/html.tar /var/www
##下载一个nginx包
scp root@172.25.78.250:/mnt/nginx/nginx-1.17.4.tar.gz /mnt/docker
vim /mnt/docker/dockerfile

FROM busybox
COPY testfile  /tmp
ADD  nginx-1.17.4.tar.gz /tmp

在这里插入图片描述
docker build -t test:v5 .

docker run -it --name vm2 test:v5  ##进去查看有nginx 
/ # cd /tmp/
/tmp # ls    

在这里插入图片描述
环境变量 ENV:设置环境变量,变量可以被后续的指令使用(不是必须的) ENV HOSTNAME server1.example.com EXPOSE:如果容器运行应用服务,可以把服务的端口暴露出去
docker history game2048
/bin/sh -c #(nop) EXPOSE 80/ tcp
在这里插入图片描述
服务的端口暴露出去 方便我们去做端口映射和用户在容器启动后去访问的 VOLUME:申明数据卷,通常指定的是应用的数据挂载点
#后面会有专门去讲解的
#目的:容器数据持久化的 VOLUME ["/var/www/html"]

3:【创建目录】

vim /mnt/docker/dockerfile

 FROM busybox
 COPY testfile /tmp
 ADD nginx-1.17.4.tar.gz /tmp 
 VOLUME ["/data"] #在启动容器的时候会帮我们自动的新建

在这里插入图片描述
docker build -t test:v6 .
在这里插入图片描述
docker run -it --name vm1 test:v6
/ # ls ##有data
/ # cd data/
/ # touch file ##创建一个文件
在这里插入图片描述
此时再打开一个shell连接server1查看
docker ps -a
docker inspect 20d880b418b3
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
##看到容器中的/data目录与宿主机上的一个新建的本地目录发生了联系

在宿主机中 进入到这个目录中去:(注意:此目录是docker引擎自动帮我们创建出来的,目录名是随机生成的)  
cd  /var/lib/docker/volumes/7b5b369b9e45e050d0d36d2c01812c8977a7fee7a1275dff26f22b36f0e3cc08/_data
ls  ##有创建的file文件 
touch redhat  ##在宿主机建立文件,容器中/data目录也会有此文件 
在容器中: 
/data # ls  ##有宿主机创建的文件redhat

在这里插入图片描述
在这里插入图片描述>
4:如需自己创建,手工指定挂载点

如不存在 会自动创建 /opt/data(宿主机上的路径 如果没有会自动帮我们创建) :/data(容器内的路径)   

docker run -it --name vm2 -v /opt/data:/data
test:v6
/ # cd /data/
/data # ls
/data # touch westos
/data # ls
/data # exit
在这里插入图片描述
退出后在宿主机查看:
cd /opt/ --> ls
cd data/ --> ls

##有容器建立的westos文件 在宿主机写westos文件,然后在容器中查看
echo ‘hello’ > westos
cat westos
在这里插入图片描述
容器中查看(因为以exit退出,所以要重新启动进入容器) docker start vm2
docker attach vm2
/ # cd data/
/data # cat westos ##有在宿主机写的内容
在这里插入图片描述

5:
WOEKDIR:为RUN CMD ENTRYPOINT ADD COPY 指令设置镜像中的当前工作目录(类似于cd
)

如果目录不存在会自动创建 RUN:在容器中运行命令并创建新的镜像层,常用于安装包  
容器瘦身:每一个RUN指令都会构建一层镜像层
尽可能将 多个命令放在一个RUN指令下
 eg:RUN yum clean all && yum repolist  
  
CMD与ENTRYPOIN1T:这两个指令都是用于设置容器启动后执行的命令,
但CMD会被docker  run后面的命令覆盖,而ENTRYPOINT不会被忽略,一定会被执行 docker
run后面的参数可以传递给ENTRYPOINT指令当作参数
dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后一个有效 	
 CMD与ENTRYPOINT(容器启动后要运行的!!) 
 RUN :在创建容器的时候!!!(在容器中)  

两种书写格式的区别 shell exec 先举一个简单的例子:
cd /mnt/docker (shell的方式)
vim dockerfile

 FROM busybox 
 ENV name world  #ENV:定义变量
 ENTRYPOINT echo "hello $name"

在这里插入图片描述
docker build -t test:v7 .
在这里插入图片描述
docker run --rm test:v7 ##(一次性的 运行停止后就删除)
docker ps -a ##并没有容器,因为已经删除
在这里插入图片描述

区别:
1):exec的方式

vim dockerfile

FROM busybox
ENV name world 
ENTRYPOINT ["/bin/echo","hello,$name"]

在这里插入图片描述
docker build -t test:v9.
docker run --rm test:v9 #发现问题 变量无法被解析
在这里插入图片描述
2)shell的方式

shell格式底层会调用/bin/sh -c 来执行命令,可以解析变量, 而exec格式不会,所以我们需要修改写法
vim dockerfile

 FROM busybox ENV name world ENTRYPOINT
["/bin/sh","-c","echo hello,$name"]

docker build -t test:v10 .  
docker run --rm test:v10          ##变量被解析

在这里插入图片描述
在这里插入图片描述
增加参数:

exec格式时,ENTRYPOINT可以通过CMD提供的额外参数,CMD的额外参数可以在容器启动时动态替换,
在shell格式时ENTRYPOINT会忽略任何CMD或docker run提供的参数

vim dockerfile

 FROM busybox
 ENTRYPOINT ["/bin/echo","hello"]
 CMD ["world"]

在这里插入图片描述
docker build -t test:v11 .
docker run --rm test:v10 westos
westos 覆盖了dockerfile CMD后面的world值
在这里插入图片描述

镜像的优化

选择最经简的基础镜像 减少镜像的层数 清理镜像构建的中间产物 注意优化网络请求 尽量去构建缓存 使用多阶段构建镜像
前提:保证镜像存在于本地
ls ##有rhel7.tar 

docker load -i rhel7.tar ##导入此镜像
docker images
在这里插入图片描述
cd /mnt/docker
cp /etc/yum.repos.d/westos.repo .
##复制yum文件到当前目录
cat westos.repo
在这里插入图片描述
实例:部署nginx

1:vim /mnt/docker/dockerfile

FROM rhel7 
EXPOSE 80
MAINTAINER dd@westos.org 
COPY westos.repo /etc/yum.repos.d/   
RUN rpmdb --rebuilddb  #重新构建rpm数据库 如不执行这一条命令会报错  
RUN yum install -y gcc   make pcre-devel zlib-devel 
ADD nginx-1.17.4.tar.gz /mnt 
WORKDIR  /mnt/nginx-1.17.4   ##WORKDIR 相当于命令 cd
RUN ./configure  --prefix=/usr/local/nginx 
RUN make 
RUN make install 
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
#通过exec的方式,nginx的启动方式

在这里插入图片描述
docker build -t nginx:v1 .
在这里插入图片描述
docker images
在这里插入图片描述

2:给镜像"瘦身":减少中间产物

vim dockerfile

FROM rhel7 
EXPOSE 80 
MAINTAINER dd@westos.org 
COPY  westos.repo /etc/yum.repos.d/ 
RUN rpmdb --rebuilddb 
RUN yum install -y  gcc make pcre-devel zlib-devel && yum clean all #清理yum缓存 
ADD nginx-1.17.4.tar.gz /mnt 
WORKDIR /mnt/nginx-1.17.4 
RUN ./configure --prefix=/usr/local/nginx 
RUN make 
RUN make install 
RUN rm -rf /mnt/nginx-1.17.4 #删除原始编译路径 
CMD  ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
# 注意:一但改动 缓存就不能用了 
docker build -t nginx:v2 .  
docker images

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3:给镜像"瘦身":减少镜像层数 ,合并多个RUN

注意:修改了指令 哪怕是一个空格 缓存就不能用了 使用缓存可以加快镜像构建速度

vim dockerfile

 FROM rhel7 
 EXPOSE 80 
 MAINTAINER dd@westos.org
 COPY  westos.repo /etc/yum.repos.d/ 
 ADD nginx-1.17.4.tar.gz /mnt 
 WORKDIR /mnt/nginx-1.17.4 
 RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && yum clean all && ./configure  --prefix=/usr/local/nginx && make && make install && rm -rf /mnt/nginx-1.17.4 
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

docker build -t nginx:v3 .  
docker images

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
层数对比:
docker history nginx:v1
docker history nginx:v2
docker history nginx:v3 ##层数最少
在这里插入图片描述
在这里插入图片描述
镜像的优化(续) 使用多阶段构建镜像 #比较优秀的方式(杀手锏)

细看dockerfile 我们其实只需要编译好的nginx的二进制文件 , 也就是只取做好的nginx环境,而不要部署nginx的过程

vim dockerfile

FROM rhel7:latest as build 
EXPOSE 80 
MAINTAINER  dd@westos.org 
COPY westos.repo /etc/yum.repos.d/ 
ADD  nginx-1.17.4.tar.gz /mnt 
WORKDIR /mnt/nginx-1.17.4 
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && yum clean all && ./configure --prefix=/usr/local/nginx && make && make install && rm -rf /mnt/nginx-1.17.4
#以上只是一个桥梁

FROM rhel7:latest #基于rhel7的基础镜像 
EXPOSE 80 
MAINTAINER dd@westos.org
VOLUME ["/usr/local/nginx/html"] 
COPY --from=build /usr/local/nginx  /usr/local/nginx #从上一层的构建中拷贝 
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

docker build -t nginx:v4 . #可以发现会很快,安装包完全使用缓存 
docker images    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
那我们有没有办法去减小基础镜像
https://github.com/search?utf8=%E2%9C%93&q=distroless&type=
谷歌为我们提供了非常精简的镜像

docker容器

1.运行容器

docker run是启动容器的方法

docker run ubuntu pwd
docker run ubuntu ls
docker ps -a

在这里插入图片描述
在这里插入图片描述

# -a会显示所有状态的容器,可以看到,之前的容器已经退出了,状态为exited
# 但是“一闪而过”的容器通常不是我们想要的结果,我们希望容器能够保持running状态,这样才能被我们使用,让容器长期运行
如何让容器保存运行呢?
因为容器的生命周期依赖于启动时执行的命令,只要该命令不结束,容器也就不会退出

docker run ubuntu /bin/bash -c ‘while true;do sleep 1;done’

##会发现退不出去,只有另外打开一个shell进行stop来停止
#while语句让bash不会退出,可以打开另一个终端查看容器的状态
在这里插入图片描述
再打开一个shell连接server1查看
docker ps -a
docker stop 0ddba8b13ae4
在这里插入图片描述
##通过while启动的容器虽然能够保持运行,但实际上没有干什么有意义的事情,容器常见的用途是运行后台服务

##–name指定容器的名字
docker run --name “my_http_server” -d httpd
docker ps
docker inspect 3e938fd312f7 ##查看信息
在这里插入图片描述
在这里插入图片描述
curl 172.17.0.2
ifconfig
在这里插入图片描述
##安装brctl命令
yum whatprovides */brctl
yum install bridge-utils-1.5-9.el7.x86_64 -y
在这里插入图片描述
brctl show
在这里插入图片描述

【attach 和 exec】

两种进入容器的方法
我们经常需要进入到容器里去做一些工作,比如查看日志,调式,启动其他进程等,
有两种方法进入容器:attach  exec
再此处,因为进入容器需要用到yum,所以镜像也得包含yum
所以用文件创建镜像,文件内容写好yum配置

vim /mnt/docker/dockerfile

FROM rhel7:latest 
COPY westos.repo  /etc/yum.repos.d/ 
RUN rpmdb --rebuilddb && yum clean all 
docker build  -t test:v1 .  
##用文件做镜像 所以以下的比较就用test:v1镜像

在这里插入图片描述
在这里插入图片描述
1:attach

-d 以后台的方式启动

 docker run -d test:v1 /bin/bash -c "while true; do sleep 1;echo I_am_in_container;done"

docker ps
docker attach 20a96a916dc4
##会一直执行下去
在这里插入图片描述
##通过docker attach可以attach到容器启动命令的终端 再打开一个终端server1,停止运行的容器

docker stop 20a96a916dc4
在这里插入图片描述

2:exec

docker run -d test:v1 /bin/bash -c  "while true; do sleep1;echo I_am_in_container;done" 

-it:以交互模式打开pseudo-TTY,执行bash,其结果就是打开了一个bash终端

docker exec -it 19e1e1338cdc85405deecdb9190802fbaf09a50f1552e7368c067af08083b2d6  bash
 
bash-4.2# yum whatprovides */ps
bash-4.2# yum install  procps-ng-3.3.10-17.el7.x86_64 -y
bash-4.2# ps -elf  ##查看所有的线程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
attach与exec主要的区别

1.attach直接进入容器启动命令的终端,不会启动新的进程
2.exec则是在容器中打开新的终端,并且可以启动新的进程
3.如果想直接在终端中查看启动命令的输入,用attach,其他情况使用exec

#当然,如果只是为了查看启动命令的输出,可以使用docker logs命令 docker logs -f c72e8ee26615
-f的作用与tail -f 类似,能够持续打印输出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值