Docker(二)Dockerfile构建镜像

基本概念:

1. dockerfile 最佳实践
Docker(二)Dockerfile构建镜像_第1张图片
2. dockerfile常用指令

  • FROM 指定base镜像,如果本地不存在会从远程仓库下载
  • MAINTAINER 设置镜像的作者,比如用户邮箱等
  • COPY 把文件从build context复制到镜像支持两种形式:COPY src dest 和 COPY [“src”, “dest”]
    src必须指定build context中的文件或目录
  • ADD 用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像: ADD html.tar /var/www ADD http://ip/html.tar /var/www
  • ENV 设置环境变量,变量可以被后续的指令使用: ENV HOSTNAME sevrer1.example.com
  • EXPOSE 如果容器中运行应用服务,可以把服务端口暴露出去: EXPOSE 80
  • VOLUME 申明数据卷,通常指定的是应用的数据挂在点: VOLUME ["/var/www/html"]
  • WORKDIR 为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工 作目录,如果目录不存在会自动创建。
  • RUN 在容器中运行命令并创建新的镜像层,常用于安装软件包: RUN yum install -y vim
  • CMD 与 ENTRYPOINT 这两个指令都是用于设置容器启动后执行的命令,但CMD会被 docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会被执行。
  • docker run后面的参数可以传递给ENTRYPOINT指令当作参数。 Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后 一个有效。

一、导入rhel7的镜像,以常规方式创建rhel7的容器

1.导入镜像,查看已有镜像

[root@server1 ~]# ls
docker  game2048.tar  nginx.tar  rhel7.tar  ubuntu.tar
[root@server1 ~]# docker load -i rhel7.tar 
e1f5733f050b: Loading layer  147.1MB/147.1MB
[root@server1 ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
game2048            latest              19299002fdbe        2 years ago         55.5MB
ubuntu              latest              07c86167cdc4        3 years ago         188MB
rhel7               latest              0a3eb3fde7fd        4 years ago         140MB

在这里插入图片描述
在这里插入图片描述
2.查看原始镜像的层数

[root@server1 ~]# docker history rhel7:latest
IMAGE               CREATED             CREATED BY          SIZE                COMMENT
0a3eb3fde7fd        4 years ago                             140MB               Imported from 

在这里插入图片描述
3.创建容器vm2并以bash的方式运行镜像,这样就可以在其中直接使用命令行,在容器中配置yum源

[root@server1 ~]# docker run -it --name vm2 rhel7 bash
bash-4.2# ls
bin   dev  home  lib64	mnt  proc  run	 srv  tmp  var
boot  etc  lib	 media	opt  root  sbin  sys  usr
bash-4.2# cd  /etc/yum.repos.d
bash-4.2# ls
rhel7.repo
bash-4.2# vi dvd.repo
 dvd.repo文件内容:
     [dvd]
     name=yum
     baseurl=http://172.25.19.250/rhel7.3
     gpgcheck=0
     
bash-4.2# yum repolist

Docker(二)Dockerfile构建镜像_第2张图片
4.在容器中安装httpd,会出现报错(Rpmdb checksum is invalid: dCDPT(pkg checksums): systemd-libs.x86_64 0:219-30.el7 - u),这是因为索引数据库有问题,出现这个问题时会非0退出,运行指令 rpmdb --rebuliddb,重新构建仓库即可,重新构建之后再次安装httpd
注意:联网的话可以从网上下载仓库

bash-4.2# yum install -y httpd
Skipping unreadable repository '///etc/yum.repos.d/rhel7.repo'
Rpmdb checksum is invalid: dCDPT(pkg checksums): systemd-libs.x86_64 0:219-30.el7 - u
bash-4.2# rpmdb --rebuilddb 
bash-4.2# yum install -y httpd
Skipping unreadable repository '///etc/yum.repos.d/rhel7.repo'
Package httpd-2.4.6-45.el7.x86_64 already installed and latest version
Nothing to do
bash-4.2# exit

在这里插入图片描述

  • 安装完httpd之后出现的报错
    在这里插入图片描述

在这里插入图片描述
二、以dockerfile的方式构建容器

1.创建docker目录,编辑Dockerfile,编辑yum.repo文件

[root@server1 ~]# cd /tmp
[root@server1 tmp]# ls
[root@server1 tmp]# mkdir docker
[root@server1 tmp]# ls
docker
[root@server1 tmp]# cd docker/
[root@server1 docker]# ls
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# vim yum.repo

Docker(二)Dockerfile构建镜像_第3张图片
Dockerfile文件的内容如下:

FROM rhel7      ##从哪一个镜像获取
COPY yum.repo /etc/yum.repos.d/yum.repo     
##将宿主机的yum.repo文件复制到容器的 /etc/yum.repos.d/yum.repo 目录下
RUN rpmdb --rebuilddb && yum install -y httpd  ##运行rpmdb --rebuilddb 和yum install -y httpd命令
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]     ##开启httpd服务

yum.repo文件的内容如下:

[yum]
name=yum
baseurl=http://172.25.19.250/rhel7.3
gpgcheck=0

2.构建镜像,可以看到构建镜像一共有四步,每一步都是dockerfile中写入的步骤,他会从上往下执行文件中的内容

注意构建镜像到当前目录,不能构建到/下,文件太大

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

Docker(二)Dockerfile构建镜像_第4张图片
Docker(二)Dockerfile构建镜像_第5张图片
3.查看镜像,镜像的层数和构建过程中显示的一致

[root@server1 docker]# docker images
[root@server1 docker]# docker history rhel7:v1

Docker(二)Dockerfile构建镜像_第6张图片
4.删除正在运行的容器vm1,运行刚刚构建的镜像创建新的容器,并且映射本地的80端口

[root@server1 docker]# docker rm -f vm1
vm1
[root@server1 docker]# netstat -tnlp

Docker(二)Dockerfile构建镜像_第7张图片

[root@server1 docker]# docker run -d --name apache  -p 80:80 rhel7:v1
f77be4feb196a2d6e24ecb65130f14593c8a64ff1548689c8ab49d3298f082fd
[root@server1 docker]# netstat -tnlp

Docker(二)Dockerfile构建镜像_第8张图片
可以在浏览器中访问宿主机的IP,这是会看到httpd的默认测试页
Docker(二)Dockerfile构建镜像_第9张图片
5.再次编辑dockerfile,编辑一个index.html的测试页

[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# vim index.html
[root@server1 docker]# ls
Dockerfile  index.html  yum.repo

在这里插入图片描述
dockerfile中新增加了一行:

FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo
RUN rpmdb --rebuilddb && yum install -y httpd
COPY index.html /var/www/html/index.html   
 ##新增加的内容是这一行,表示将index.html文件复制为镜像的/var/www/html/index.html文件
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

6.再次构建镜像

[root@server1 docker]# docker build -t rhel7:v2 .

Docker(二)Dockerfile构建镜像_第10张图片
可以对比出和上一个镜像前两行都一样,也就是在原有的基础上叠加(这个说法可能不太准确,理解就好)
Docker(二)Dockerfile构建镜像_第11张图片

7.删除容器apache,并且在/tmp/docker目录下新建一个目录website,并将index.html文件移动到这个目录下

[root@server1 docker]# docker rm -f apache
apache
[root@server1 docker]# ls
Dockerfile  index.html  yum.repo
[root@server1 docker]# mkdir website
[root@server1 docker]# mv index.html website/

Docker(二)Dockerfile构建镜像_第12张图片
8.创建一个新的容器,挂载/tmp/docker/website目录,并且设置端口映射 (-v表示配置挂载)

[root@server1 docker]# docker run -d --name apache -p 80:80 -v /tmp/docker/website:/var/www/html rhel7:v2
647a50483a6cc470d43b577a454626ef787fb5aacc1969a27ce2636635b7f405

在这里插入图片描述
9.访问宿主机IP,可以看到index.html文件中写的内容

Docker(二)Dockerfile构建镜像_第13张图片
10.查看容器的详细信息,可以找到容器的具体挂载信息

[root@server1 docker]# docker inspect apache

Docker(二)Dockerfile构建镜像_第14张图片
Docker(二)Dockerfile构建镜像_第15张图片
11.修改index.html文件的内容,在浏览器中刷新页面可以看到发生变化

[root@server1 docker]# ls
Dockerfile  website  yum.repo
[root@server1 docker]# cd website/
[root@server1 website]# ls
index.html
[root@server1 website]# vim index.html 

Docker(二)Dockerfile构建镜像_第16张图片
Docker(二)Dockerfile构建镜像_第17张图片
三、shell和exec的区别

  • shell合适底层会直接调用/bin/sh-c执行命令,可以识别到变量
  • 而exec需要写成这样的格式: ENTRYPOINT ["/bin/sh",“c”, “echo hello,$name”]
  • exec格式ENTRYPOINT可以通过CMD提供额外参数,CMD的额外参数可以在容器启动时替换,但shell格式ENTRYPOINT会忽略所有CMD或docker run提供的参数

1.导入busybox的镜像,这个镜像比较小,是在这里进行验证比较适用

[root@server1 ~]# ls
busybox.tar  docker  game2048.tar  nginx.tar  rhel7.tar  ubuntu.tar
[root@server1 ~]# docker load -i busybox.tar
8a788232037e: Loading layer   1.37MB/1.37MB
Loaded image: busybox:latest

Docker(二)Dockerfile构建镜像_第18张图片
2.使用shell格式编辑dockerfile

[root@server1 docker]# vim Dockerfile 
文件内容:
FROM busybox
ENV name world
ENTRYPOINT echo "hello,$name"

在这里插入图片描述
3.构建镜像,并查看运行时显示的内容

[root@server1 docker]# docker build -t busybox:v1 .
[root@server1 docker]# docker run --rm busybox:v1
hello,world

Docker(二)Dockerfile构建镜像_第19张图片
4.使用exec格式编辑dockerfile,构建镜像运行容器,可以看到显示的内容没有识别变量

[root@server1 docker]# vim Dockerfile 

文件内容:
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello,$name"]

[root@server1 docker]# docker build -t busybox:v2 .

[root@server1 docker]# docker run --rm busybox:v2 
hello,$name

Docker(二)Dockerfile构建镜像_第20张图片
5.使用加了执行环境的exec格式编辑dockerfile,构建镜像,运行容器

[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# docker build -t busybox:v3 .

FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh","c", "echo hello,$name"]
[root@server1 docker]# docker run --rm busybox:v3
hello,world

Docker(二)Dockerfile构建镜像_第21张图片
(5)使用shell+exec格式,构建镜像并运行容器,变量被识别,但是发现在运行容器的时候加上新的变量dockerfile中的CMD后的内容会被覆盖

[root@server1 docker]# vim Dockerfile 
[root@server1 docker]# docker build -t busybox:v4 .

FROM busybox
ENTRYPOINT ["/bin/echo","hello"]
CMD ["world"]
[root@server1 docker]# docker run --rm busybox:v4
hello world

[root@server1 docker]# docker run --rm busybox:v4 westos
hello westos

Docker(二)Dockerfile构建镜像_第22张图片
补充:
1.docker引擎会自动分配目录,默认目录 /var/lib/docker
2.WORKDIR 类似于cd 切换目录
3.在dockerfile中cmd会被覆盖 entrpoint不会
4.运行容器时加参数(–rm )运行之后直接删除
5.env可以指定变量
6.删除镜像的时候要先删除容器(rm)再删除镜像(rmi),因为不删除容器的话镜像就相当于是在被一个进程占用,无法删除
7.在运行交互式的容器(rhel)时需要加上bash
8.在dockerfile中from后加的是镜像的名称
run 表示运行指令
copy可以将当前目录中的指定文件复制到容器中的目的路径,一定是当前目录中的文件
cmd 表示运行,在容器启动的时候运行,只能有一个
9.容器中尽管显示的是超级用户但还是会被限制的
10.docker有自己的仓库

你可能感兴趣的:(企业部分)