Docker镜像的创建方法

一、Docker镜像

1.1 镜像的概念

镜像是创建容器的基础。

镜像是一个只读的模板文件,里面包含运行容器中的应用程序所有需要的所有内容(应用程序文件、配置文件、运行库文件、依赖包等)。

1.2 镜像结构的分层

Docker 镜像由多个只读层组成,每个层都包含了文件系统的一部分。

这些层按照从底向上的顺序依次叠加,形成一个完整的镜像。

镜像的最底层是一个基础镜像(Base Image),上面叠加了一系列更高层的镜像,每个层都是前一个层的增量变化。

在容器启动时,Docker 引擎会将这些层通过联合文件系统合并成一个容器文件系统。

在容器运行过程中,Docker 引擎将修改操作写入一个可写层(Writeable Layer),该层仅保存容器运行时的状态和数据。

这种分层和联合文件系统的设计使得镜像的创建和传播非常高效,节省了存储空间和下载时间。

二、Docker镜像的创建

创建镜像有两种方法,分别为基于已有镜像创建基于Dockerfile创建

2.1 基于现有镜像创建

基于已有镜像创建主要使用 docker commit 命令。

本质上就是把一个容器里面运行的程序和该程序的运行环境打包,生成新的镜像

#基本格式
docker commit [选项] 容器ID/名称 仓库名称:[标签]

##常用选项##
-m 说明信息;
-a 作者信息;
-p 生成过程中停止容器的运行。

2.1.1 创建思路

1)先用现有镜像创建启动容器 ,使用 docker run命令;

2)再进入容器进行内容更新 ,使用docker exec命令;

3)最后提交成新的镜像 ,使用 docker commit命令。

2.1.2 举个例子

首先启动一个镜像,在容器里做修改

docker create -it centos:7 bash
docker ps -a

然后将修改后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像

docker commit -m "test" -a "centos" fa7610873212 centos:test


docker images

2.2 基于Dockerfile 创建

除了手动生成Docker镜像之外,可以使用Dockerfile自动生成镜像。

Dockerfile是由多条的指令组成的文件,其中每条指令对应 Linux 中的一条命令,Docker 程序将读取Dockerfile 中的指令生成指定镜像。

Dockerfile结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#“号开头的注释。

2.3  实战案例:基于 busybox 制作httpd镜像

[root@localhost ~]#docker run -it --name b1  busybox
#启动  busybox 容器

/ # hostname   -i
/ # httpd --help                                 进入容器查看  httpd 的帮助
/ # mkdir /data/html -p                          新建主站点目录
/ # echo testpage  > /data/html/index.html       新建站点目录
/ # httpd -f  -h  /data/html/                   -f 前台启动  -h 指定主站点
/ # httpd -f  
[root@localhost ~]#docker commit -a "xia" -c 'CMD /bin/httpd -f -h /data/html' -c "EXPOSE 80" b1  httpd-b:1.0
sha256:a18cc4d35c341a0fe6ddd9a3c5d93f9c07d65b6b8daaf3cf102cf092a8291bc2

[root@localhost ~]# docker images |head -n 2
REPOSITORY                                       TAG       IMAGE ID       CREATED          SIZE
httpd-b                                          1.0       a18cc4d35c34   12 minutes ago   1.24MB

启动制作好的容器

[root@localhost ~]# docker run -d --name web1 -P httpd-b:1.0 
90ba8a510c5bdba12fbf79ebc7ab0cba5bbbf0e4b700b3b1749a7b1a39a46988
[root@localhost ~]# docker port  web1
80/tcp -> 0.0.0.0:32768
80/tcp -> [::]:32768



curl 192.168.10.20:32768

2.4 实战案例: 基于官方镜像生成的容器制作tomca镜像

下载启动tomcat 容器

[root@localhost ~]# docker run -d -p 8080:8080 tomcat 
#下载启动 tomcat  容器
a6409a9b358506a45e59ed66f53d95bd0ee2d6ea8f03873fd70a2fb6dfc8996c
[root@localhost ~]# docker ps -a
#  先查看的  id
CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS                                       NAMES
a6409a9b3585   tomcat    "catalina.sh run"   7 seconds ago   Up 6 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   reverent_sutherland
[root@localhost ~]# docker exec -it a64 bash
# 进入容器
root@a6409a9b3585:/usr/local/tomcat# cp -a webapps.dist/*  webapps/
#复制页面文件

打包成镜像

[root@localhost ~]# docker commit -m "add  webapps app" -a "xia" a6409a9b3585 tomcat:10.0.14
sha256:0f1d4fec2065e777b20993297f58fe3cc573d45e7e6f61db04c0eb8c8bbada5a
[root@localhost ~]# docker images |head -n 2
REPOSITORY                                       TAG       IMAGE ID       CREATED          SIZE
tomcat                                           10.0.14   0f1d4fec2065   19 seconds ago   684MB
#启动镜像
[root@localhost ~]# docker run -d --name t1  -p 8081:8080 tomcat:10.0.14
b2d79d63a9b9392317246c9ab4b38c72c77d64c1fcb8aae15ffabf3aec961b03
[root@localhost ~]# docker port t1
8080/tcp -> 0.0.0.0:8081
8080/tcp -> [::]:8081

2.5 实战案例:基于CentOS编译安装 nginx镜像

在CentOS 基础镜像的容器之上手动编译安装nginx,然后再将此容器提交为镜像

[root@localhost yum.repos.d]#docker run -it --name c1  centos:latest  bash
[root@0ee63ccc22fc /]# rm -rf /etc/localtime 
[root@0ee63ccc22fc /]# ln -s /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime 
[root@0ee63ccc22fc /]#useradd -r -s /sbin/nologin nginx
[root@0ee63ccc22fc /]# yum -y install gcc gcc-c++ make automake pcre pcre-devel zlib  zlib-devel openssl openssl-devel wget
[root@0ee63ccc22fc yum.repos.d]# wget http://nginx.org/download/nginx-1.18.0.tar.gz
[root@0ee63ccc22fc yum.repos.d]# tar xf nginx-1.18.0.tar.gz 
[root@0ee63ccc22fc yum.repos.d]# cd nginx-1.18.0
[root@0ee63ccc22fc nginx-1.18.0]# ./configure   --prefix=/apps/nginx
[root@0ee63ccc22fc nginx-1.18.0]#make
[root@0ee63ccc22fc nginx-1.18.0]#make  install
[root@0ee63ccc22fc yum.repos.d]# vim /apps/nginx/conf、nginx.conf
daemon off;
[root@0ee63ccc22fc nginx]# sbin/nginx -t
[root@0ee63ccc22fc nginx]# hostname -I
172.17.0.2 
[root@0ee63ccc22fc nginx]# /apps/nginx/sbin/nginx

打包成镜像

[root@localhost yum.repos.d]# docker commit  -m "nginx1.8.0" -c "CMD /apps/nginx/sbin/nginx" 0ee63ccc22fc nginx1.18.0-centos8:v1
sha256:21b4ecc1da5055aadc95321a1cd9ef96f898406bc7f61f9a2fd38eb676aba250

启动容器

[root@localhost yum.repos.d]# docker run -d -P --name web1  nginx1.18.0-centos8:v1
97f237b059231ece3617ceff7a08258e1bc9218d761cb65a09116f541ba39bb9
[root@localhost yum.repos.d]# docker run -d -p 90:80  --name web2  nginx1.18.0-centos8:v1
bc6ba2aa29fb96e532c085158f0d445248e52a556551f61e91a0cef9793e3558
[root@localhost yum.repos.d]# docker port web2
80/tcp -> 0.0.0.0:90
80/tcp -> [::]:90

三、Dockerfile 详解

3.1 Dockerfile 操作指令

3.1.1 常用的操作指令

常用指令含义
FROM指定基础镜像(是Dockerfile的第一行指令)
MAINTAINER指定镜像维护人信息(可选)
RUN指定Linux命令,如果要执行连续多条命令时建议用 ; 或 && 或 <<EOF 串起来使用
EXPOSE指定容器应用的端口
ENV设置镜像的环境变量
ADD/COPY复制文件/目录到镜像里
VOLUME指定容器的匿名数据卷
USER指定容器的运行用户
WORKDIR指定后续镜像层的工作目录
ARG指定构建镜像时传入的参数变量,docker build --build-arg 变量=值
CMD/ENTRYPOINT指定容器启动时执行的命令

3.1.2 CMD和ENTRYPOINT的区别

共同点:都可以用来指定容器启动命令。

区别:ENTRYPOINT指定的容器启动命令优先级更高

如果CMD和ENTRYPOINT同时存在,那么CMD指定的内容将作为ENTRYPOINT指定的容器启动命令的选项或参数使用。

容器启动时运行的命令优先级
docker run --entrypoint=“命令” > 镜像里的ENTRYPOINT指定的命令 > docker run … 镜像 命令 > 镜像里的CMD指定的命令

3.1.3 ADD和COPY的区别

共同点:都可以将本地的文件/目录复制到镜像里。

区别:ADD还可以通过URL下载文件复制到镜像里,还能将本地的压缩包解压后复制到镜像里。

URL下载和压缩包解压特性不能同时使用。

3.2 基于Dockerfile构建镜像的步骤

在编写 Dockerfile 时,有严格的格式需要遵循。

1)第一行 用FROM指令指明所用的基础镜像;

2)之后用MAINTAINER指令说明维护镜像的用户信息;

3)然后用镜像操作相关指令,比如RUN EXPOSE ENV ADD COPY 等指令,编写构建镜像的过程。每运行一条指令,都会给基础镜像添加新的一层;

4)结尾使用CMD/ENTRYPOINT指令指定容器启动时执行的命令;

5)最后使用docker build -t 新镜像名:标签 . [-f Dockerfile文件路径]命令构建镜像。

3.3 基于Dockerfile创建镜像应用实例

Step1 建立工作目录

mkdir  /opt/apache
cd  /opt/apache

Step2 创建并编写Dockerfile文件

vim Dockerfile

#基于的基础镜像
FROM centos:7
#维护镜像的用户信息
MAINTAINER this is apache image <hmj>

#更换镜像
RUN rm -rf /etc/yum.repos.d
ADD qh.repo /etc/yum.repos.d/

#镜像操作指令安装apache软件
RUN yum -y install httpd
#开启 80 端口
EXPOSE 80
#复制网站首页文件
ADD index.html /var/www/html/index.html

##方法一
#将执行脚本复制到镜像中
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]

##方法二
ENTRYPOINT [ "/usr/sbin/apachectl" ]
CMD ["-D", "FOREGROUND"]

Step3 编写执行脚本

vim  run.sh

rm -rf /run/httpd/*							#清理httpd的缓存
/usr/sbin/apachectl -D FOREGROUND			#指定为前台运行

#因为Docker容器仅在它的1号进程(PID为1)运行时,会保持运行。如果1号进程退出了,Docker容器也就退出了。

Step4 创建测试页面

echo "this is test web from cxk " > index.html
ls

Step5 使用Dockerfile生成镜像

docker build -t httpd:centos .   		
#注意别忘了末尾有"."

Step6 使用新的镜像运行容器并测试

使用新镜像运行容器

docker run -d -p 1216:80 httpd:centos

测试

http://192.168.10.20:1216

四、如何去缩小构建镜像的大小

1)尽可能的采用小体积的基础镜像;

2)尽可能的减少Dockerfile指令的数量;

3)在RUN指令里添加安装软件后清空yum/apt缓存、软件包的命令;

4)使用多级(多阶段)构建的方法 。

FROM 第一阶段的基础镜像 AS 别名
......
FROM 第二阶段的基础镜像
COPY --from=别名  第一阶段构建的文件/目录  当前阶段的路径
 .....
CMD/ENTRYPOINT 指定容器启动时执行的命令

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值