第5章 Dockerfile
dockerfile是一个文本的配置文件,它可以快速创建自定义的镜像。
文本内容:包含了若干的命令行,并支持#作为注释行
文本格式:基础镜像
FROM
,维护者MAINTAINER
,操作指令ADD
,**容器启动后指令CMD
**等共计4部分
总结一句Dockerfile是用来定制镜像的文本文件。
📖5.1 Docker镜像原理
思考:
Docker 镜像本质是什么?
Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
Docker 中一个tomcat镜像为什么有600MB,而一个tomcat安装包只有70多MB?
操作系统组成部分:
- 进程调度子系统
- 进程通信子系统
- 内存管理子系统
- 设备管理子系统
- 文件管理子系统
- 网络通信子系统
- 作业控制子系统
Linux文件系统由bootfs和rootfs两部分组成
bootfs
:包含bootloader(引导加载程序)和 kernel(内核)rootfs
: root文件系统,包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件- 不同的linux发行版,bootfs基本一样,而rootfs不同,如ubuntu,centos等
docker镜像原理
- Docker镜像是由特殊的文件系统叠加而成
- 最底端是 bootfs,并使用宿主机的bootfs 、
- 第二层是 root文件系统rootfs,称为base image
- 然后再往上可以叠加其他的镜像文件
- 统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。
- 一个镜像可以放在另一个镜像的上面。位于下面的镜像称为父镜像,最底部的镜像成为基础镜像。
- 当从一个镜像启动容器时,Docker会在最顶层加载一个读写文件系统作为容器
回答问题
Docker 镜像本质是什么?
是一个分层文件系统
Docker 中一个centos镜像为什么只有200MB,而一个centos操作系统的iso文件要几个个G?
Centos的iso镜像文件包含bootfs和rootfs,而docker的centos镜像复用操作系统的bootfs,只有rootfs和其他镜像层 。
Docker 中一个tomcat镜像为什么有600MB,而一个tomcat安装包只有70多MB?
由于docker中镜像是分层的,tomcat虽然只有70多MB,但他需要依赖于父镜像和基础镜像,所有整个对外暴露的tomcat镜像大小600多MB。
📖5.2 镜像制作
✅ 容器转镜像
转镜像
docker commit 容器id 镜像名称:版本号
压缩
docker save -o 压缩文件名称 镜像名称:版本号
解压
docker load –i 压缩文件名称
测试
# 创建tomcat镜像 (宿主机进行)
docker run -id --name=c_tomcat \
-p 8080:8080 \
-v $PWD:/usr/local/tomcat/webapps \
tomcat
# 进入tomcat镜像 (宿主机进行)
docker exec -it c_tomcat /bin/bash
#创建a.txt b.txt (容器中进行)
cd ~
touch a.txt b.txt
#容器转镜像 (宿主机进行)
docker commit 28b8d4dc9744 mjh_tomcat:1.0
#压缩镜像 (宿主机进行)
docker save -o lxs_tomcat.tar mjh_tomcat:1.0
#删除原来镜像 (宿主机进行)
docker rmi mjh_tomcat:1.0
#从压缩文件加载镜像 (宿主机进行)
docker load -i mjh_tomcat.tar
#产生镜像 (宿主机进行)
docker run -it --name=new_tomcat mjh_tomcat:1.0 /bin/bash
#进入查看内容 (宿主机进行)
docker exec -it c_tomcat /bin/bash
#可以看到a.txt b.txt存在,而webapps/test不存在 (容器中进行)
总结:
镜像的制作并不会将数据卷中的数据打包,只会将容器中的数据携带。
✅dockerfifile
概念
- Dockerfifile 是一个文本文件
- 包含了一条条的指令
- 每一条指令构建一层,基于基础镜像,最终构建出一个新的镜像
- 对于开发人员:可以为开发团队提供一个完全一致的开发环境
- 对于测试人员:可以直接拿开发时所构建的镜像或者通过Dockerfifile文件构建一个新的镜像开始工作了
- 对于运维人员:在部署时,可以实现应用的无缝移植
参考Dochub网址:https://hub.docker.com ,比如centos和nginx镜像
✅案例1:自定义centos7镜像。
要求:
默认登录路径为 /usr
可以使用vim
实现步骤
定义父镜像:FROM centos:7
定义作者信息:MAINTAINER lxs lxs@lxs.cn
执行安装vim命令: RUN yum install -y vim
定义默认的工作目录:WORKDIR /usr
定义容器启动执行的命令:CMD /bin/bash
通过dockerfifile构建镜像:docker bulid –f dockerfifile文件路径 –t 镜像名称:版本 .
第一步:创建centos_dockerfile
#具体代码
mkdir ~/docker-files
cd ~/docker-files
vim centos_dockerfile
第二步:配置centos_dockerfile
,继承父镜像,centos_dockerfile
具体内容 如下
FROM centos:7
MAINTAINER mjh <mjh@mjh.com>
RUN yum install -y vim
WORKDIR /usr
CMD /bin/bash
第三步:build
docker build -f ./centos_dockerfile -t lxs_centos:1 .
-f:镜像文件
-t:新镜像名
. 寻址路径
第四步:测试
#进入看效果
docker run -it --name=c2 mjh_centos:1
✅案例2:使用Dockerfile安装redis镜像
🕊️1. 安装centos7镜像和redis依赖包
🍵步骤一:查找Docker Hub 上的centos镜像
docker search centos
🍵步骤二:拉取官方的镜像,标签为7
docker pull centos:7
🍵步骤三:查看本地镜像列表REPOSITORY为centos标签为7的镜像
docker images centos:7
🍵步骤四:使用镜像centos:7以交互模式启动一个容器,在容器内执行/bin/bash命令
docker run -it centos:7 /bin/bash
此时进入容器内部,图中“705ccba62a5
”为容器ID
🍵步骤五:容器内安装Redis依赖包
yum -y install wget gcc make libgcc gcc-c++ glibc-devel
🍵步骤六:输入exit,退出容器,输入docker ps -a查看容器id
exit
docker ps -a
由此可知,容器的ID为3b898a823d80
🍵步骤七:根据容器ID创建一个新的镜像作为Redis的基础镜像
docker commit -a "huawei.com" -m "redis images" f42cb9a0bf6f(此处为容器ID注意替换为自己的容器ID) centos:7
其中: huawei.com:提交的镜像作者 3b898a823d80:容器ID redis images:提交时的说明文字 centos:7:新生成的镜像名称
🍵步骤八:查看新构建的基础镜像
docker images
由此可知,新镜像centos:7构建成功。
🕊️2. Docker根据基础镜像安装Redis
🍵步骤一:创建Redis目录
mkdir -p ~/redis/data
数据卷data目录将映射为redis容器配置的/data目录,作为redis数据持久化的存储目录。
🍵步骤二:进入创建的Redis目录,创建Dockerfile.
cd ~/redis
vi Dockerfile
🍵步骤三:输入i,编辑如下内容到Dockerfile中
FROM centos:7
WORKDIR /home
RUN wget https://repo.huaweicloud.com/redis/redis-4.0.3.tar.gz && \
tar -xvzf redis-4.0.3.tar.gz && \
mv redis-4.0.3/ redis && \
rm -f redis-4.0.3.tar.gz
WORKDIR /home/redis
RUN make && make install
Volume /data
EXPOSE 6379
CMD ["redis-server"]
🍵步骤四:完成后按“esc”键,然后输入:wq保存退出文档
🍵步骤五:通过Dockerfile创建Redis镜像
docker build -t centos_redis:4.0.3 .
🍵步骤六:查看创建的Redis镜像
docker images
说明Redis镜像创建成功,镜像名称:centos_redis,标签4.03,镜像ID ec392ba2c006。
🕊️3. 验证Redis镜像
🍵步骤一:运行容器,执行redis-server
docker run -p 6379:6379 -v /root/redis/data:/data -d centos_redis:4.0.3 redis-server --appendonly yes
命令说明: -p 6379:6379 : 将容器的6379端口映射到主机的6379端口。 -v $PWD/data:/data : 将主机中当前目录下的data挂载到容器的/data。 redis-server --appendonly yes : 在容器执行redis-server启动命令,并打开redis持久化配置。
🍵步骤二:查看容器启动状态,记录容器ID,下一步中会通过容器ID进入容器
docker ps
🍵步骤三:执行redis-cli命令连接到刚启动的容器
执行redis-cli命令连接到刚启动的容器,并敲入info命令(其中530078068cb2为上一步中查看的容器的ID)
docker exec -it 530078068cb2(此处为容器ID注意替换为自己的容器ID) redis-cli
info
说明连接redis-server成功。
🍵步骤四:使用redis容器,分别敲入以下命令:
ping
set runkey "hello redis"
get runkey
说明: ping返回PONG说明检测到 redis 服务已经启动。 set runkey "hello redis":设置runkey值为"hello redis",返回OK,说明设置成功。 get runkey:获取runkey的值,返回"hello redis"说明与设置的相匹配
✅案例3:发布springboot项目
- 定义父镜像:FROM java:8
- 定义作者信息:MAINTAINER lxs lxs@163.com
- 将jar包添加到容器: ADD springboot.jar app.jar
- 定义容器启动执行的命令:CMD ["java","-jar","app.jar"]
- 通过dockerfifile构建镜像:docker bulid –f dockerfifile文件路径 –t 镜像名称:版本 .
第一步:在docker-files中创建springboot_dockerfile
#具体代码
[root@centos7 docker-files]# vim centos_dockerfile
第二步:配置springboot_dockerfile
FROM java:8
MAINTAINER mjh <mjh@123.com>
ADD springboot.jar app.jar
CMD ["java","-jar","app.jar"]
第三步:build
docker bulid –f ./springboot_dockerfile –t app .
第四步:启动容器
docker run -id -p 9000:8080 app