实验简介
实验一:Docker-CE 环境部署
实验目标
完成 Docker-CE(社区版)在 RHEL 9.6 系统上的安装与基础配置,确保 Docker 服务正常运行并适配网络转发等核心功能。
核心操作步骤
- 配置软件仓库:通过阿里云镜像源创建 Docker 专属 YUM 仓库(关闭 GPG 校验),解决官方源访问慢 / 权限问题;
- 安装 Docker-CE :通过
dnf工具安装 Docker-CE 主程序; - 修改服务配置 :调整
docker.service文件,确保dockerd启动时启用iptables功能; - 网络参数配置 :
- 加载
br_netfilter内核模块(桥接网络过滤); - 配置
sysctl参数,开启桥接网络的 iptables 转发、IPv4 转发等,解决容器网络通信问题;
- 加载
- 启动并开机自启 :通过
systemctl启用 Docker 服务并设置开机自启。
实验意义
解决 Docker 安装的源配置、网络转发等基础问题,为后续容器操作搭建稳定的运行环境。
实验二:Docker 常规使用方法
实验目标
掌握 Docker 镜像和容器的核心操作命令,覆盖镜像的搜索 / 下载 / 导出 / 导入,容器的运行 / 管理 / 交互等基础场景。
核心操作模块
- 镜像加速配置 :修改
daemon.json配置 Docker 镜像加速器(阿里云镜像),提升镜像下载速度; - 镜像管理 :
- 查看 / 搜索 / 拉取镜像(
docker images/search/pull); - 查看镜像历史(
docker history)、导出 / 导入镜像(docker save/load)、删除镜像(docker rmi);
- 查看 / 搜索 / 拉取镜像(
- 容器管理 :
- 运行容器(后台 / 交互模式:
docker run -d/docker run -it); - 查看容器(运行中 / 全部:
docker ps/docker ps -a); - 容器生命周期控制(启动 / 停止 / 杀死:
docker start/stop/kill); - 容器交互(附着容器 / 执行命令:
docker attach/docker exec); - 容器文件传输(主机↔容器:
docker cp); - 容器提交为新镜像(
docker commit)、删除容器(docker rm)。
- 运行容器(后台 / 交互模式:
实验意义
掌握 Docker 最常用的基础命令,理解镜像与容器的生命周期关系,能完成日常的镜像 / 容器运维操作。
实验三:容器镜像构建(Dockerfile)
实验目标
熟悉 Dockerfile 的核心指令,掌握自定义镜像的构建逻辑和方法。
核心操作模块
- 基础环境准备:创建构建目录,编写 Dockerfile 文件;
- 核心指令实操 :
FROM:指定基础镜像(如busybox:latest);COPY/ADD:复制文件到镜像(ADD 支持自动解压压缩包);LABEL:添加镜像元数据(如作者信息);ENV:设置环境变量(可在后续指令中引用);EXPOSE:声明容器暴露的端口(仅标识,不自动映射);VOLUME:定义匿名卷(容器运行时自动挂载,持久化数据);WORKDIR:设置容器工作目录(后续指令的默认路径);CMD/ENTRYPOINT:定义容器启动命令(CMD 可被覆盖,ENTRYPOINT 为固定入口);
- 镜像构建与验证 :
- 通过
docker build -t 镜像名:版本 .构建镜像; - 查看镜像构建历史(
docker history); - 运行镜像验证指令效果(如卷挂载、环境变量、工作目录等)。
- 通过
实验意义
理解自定义镜像的构建逻辑,掌握 Dockerfile 核心指令的区别与用法(如 COPY vs ADD、CMD vs ENTRYPOINT),能根据业务需求编写自定义镜像,是 Docker 镜像定制的核心技能。
实验四:Docker 镜像优化实践
实验目标
理解 Docker 镜像体积过大的核心原因,掌握 "缩减镜像层、多阶段构建、使用精简基础镜像"3 种核心优化策略,能通过实操完成镜像瘦身,提升镜像传输与部署效率。
核心操作模块
- 基础环境准备 :
- 准备
nginx-1.26.tar.gz源码包; - 创建独立构建目录,编写不同版本的优化 Dockerfile。
- 准备
- 优化策略实操 :
- 缩减镜像层:合并多条 RUN 指令,通过
&&串联命令,同步执行依赖安装、程序编译与中间产物清理(如删除源码包、清理 yum 缓存); - 多阶段构建:使用
AS build定义构建阶段,仅在构建阶段完成程序编译,运行阶段通过COPY --from=build复制编译产物,舍弃构建依赖; - 采用精简基础镜像:引入 Google distroless 超精简镜像,仅复制程序运行必需的文件(依赖库、配置文件、可执行程序),去除冗余组件。
- 缩减镜像层:合并多条 RUN 指令,通过
- 镜像构建与验证 :
- 通过
docker build -t 镜像名:版本 .构建不同优化版本的镜像; - 使用
docker images对比优化前后的镜像体积; - 运行镜像(
docker run -d -p 80:80 镜像名:版本),验证程序正常运行。
- 通过
实验意义
掌握镜像优化的核心逻辑(仅保留运行必需文件),解决镜像存储占用高、传输慢、部署耗时久等问题;理解不同优化策略的适用场景,能根据实际业务需求(测试 / 生产环境)选择合适的优化方案,是 Docker 生产环境部署的关键技能。
部署docker
配置软件仓库并安装docker-ce
#利用阿里云部署软件仓库
[root@docker-node1 ~]# cat > /etc/yum.repos.d/docker.repo << EOF
[docker]
name = docker
baseurl = https://mirrors.aliyun.com/docker-ce/linux/rhel/9.6/x86_64/stable/
gpgcheck = 0
EOF
[root@docker-node1 ~]# dnf makecache
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 "rhc" 或 "subscription-manager" 进行注册。
docker 7.3 kB/s | 46 kB 00:06
AppStream 3.1 MB/s | 3.2 kB 00:00
BaseOS 2.7 MB/s | 2.7 kB 00:00
元数据缓存已建立。
[root@docker-node1 ~]# dnf search docker
正在更新 Subscription Management 软件仓库。
无法读取客户身份
本系统尚未在权利服务器中注册。可使用 "rhc" 或 "subscription-manager" 进行注册。
上次元数据过期检查:0:00:13 前,执行于 2026年03月14日 星期六 14时55分07秒。
==================================== 名称 和 概况 匹配:docker =====================================
docker-buildx-plugin.x86_64 : Docker Buildx plugin for the Docker CLI
docker-ce-rootless-extras.x86_64 : Rootless support for Docker
docker-compose-plugin.x86_64 : Docker Compose plugin for the Docker CLI
docker-model-plugin.x86_64 : Docker Model Runner plugin for the Docker CLI
pcp-pmda-docker.x86_64 : Performance Co-Pilot (PCP) metrics from the Docker daemon
podman-docker.noarch : Emulate Docker CLI using podman
======================================== 名称 匹配:docker =========================================
docker-ce.x86_64 : The open-source application container engine
docker-ce-cli.x86_64 : The open-source application container engine
[root@docker-node1 ~]# dnf install docker-ce -y
[root@docker-node1 ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true
[root@docker-node1 ~]# echo br_netfilter > /etc/modules-load.d/docker_mod.conf
[root@docker-node1 ~]# modprobe -a br_netfilter
[root@docker-node1 ~]# cat > /etc/sysctl.d/docker.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
[root@docker-node1 ~]# sysctl --system
[root@docker-node1 ~]# systemctl enable --now docker
docker的常规使用方法
配置docker加速器
[root@docker-node1 ~]# cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://docker.1ms.run"]
}
EOF
[root@docker-node1 ~]# systemctl restart docker
[root@docker-node1 ~]# docker info
Client: Docker Engine - Community
Version: 29.3.0
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.31.1
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v5.1.0
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 29.3.0
Storage Driver: overlayfs
driver-type: io.containerd.snapshotter.v1
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
CDI spec directories:
/etc/cdi
/var/run/cdi
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 301b2dac98f15c27117da5c8af12118a041a31d9
runc version: v1.3.4-0-gd6d73eb8
init version: de40ad0
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 5.14.0-570.12.1.el9_6.x86_64
Operating System: Red Hat Enterprise Linux 9.6 (Plow)
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 732.5MiB
Name: docker-node1
ID: 8f6c1bf7-2e8d-449f-a3a9-a8f31708c06c
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
::1/128
127.0.0.0/8
Registry Mirrors:
https://docker.1ms.run/
Live Restore Enabled: false
Firewall Backend: iptables
docker常用命令
#镜像查看
[root@docker-node1 ~]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
#搜索镜像
[root@docker-node1 ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL
nginx Official build of Nginx. 21206
#下载镜像
[root@docker-node1 ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
9eef040df109: Pull complete
206356c42440: Pull complete
75a1d70aee50: Pull complete
a9d395129dce: Pull complete
df9da45c1db2: Pull complete
18a071c04bd1: Pull complete
79697674b897: Pull complete
d99947bc9177: Download complete
23abb0f9ce55: Download complete
Digest: sha256:bc45d248c4e1d1709321de61566eb2b64d4f0e32765239d66573666be7f13349
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@docker-node1 ~]# docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
96cfb76e59bd: Download complete
61dfb50712f5: Pull complete
Digest: sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
#查看镜像提交历史
[root@docker-node1 ~]# docker history busybox:latest
IMAGE CREATED CREATED BY SIZE COMMENT
b3255e7dfbcd 17 months ago BusyBox 1.37.0 (glibc), Debian 13 4.49MB
[root@docker-node1 ~]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
busybox:latest b3255e7dfbcd 6.7MB 2.22MB
nginx:latest bc45d248c4e1 237MB 65.8MB
#导出镜像
[root@docker-node1 ~]# docker save -o game2048-latest.tar timinglee/game2048:latest
#删除镜像
[root@docker-node1 ~]# docker rmi timinglee/mario:latest
#导入镜像
[root@docker-node1 ~]# docker load -i game2048-latest.tar
#运行镜像
[root@docker-node1 ~]# docker run -d --name web nginx:1.26
Unable to find image 'nginx:1.26' locally
1.26: Pulling from library/nginx
4fd410795c0f: Pull complete
8a628cdd7ccc: Pull complete
7a0654aeb922: Pull complete
d44088bb6ae8: Pull complete
5e98d206134b: Pull complete
6923759e66ab: Pull complete
9ebfb40fb06b: Pull complete
f17adcc09044: Download complete
5c2c3686e536: Download complete
Digest: sha256:41b194461e4bae16f9b25d68b0976ed4735b89ca625c89aad88e1c1c3b7e8860
Status: Downloaded newer image for nginx:1.26
c08933f2a30aacb3167cfae66d42c986fba9f44bf0ddecb3f37008d83a7635f4
#查看运行容器
[root@docker-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c08933f2a30a nginx:1.26 "/docker-entrypoint...." 28 seconds ago Up 28 seconds 80/tcp web
#查看所有容器
[root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c08933f2a30a nginx:1.26 "/docker-entrypoint...." About a minute ago Up About a minute 80/tcp web
#交互模式运行容器
[root@docker-node1 ~]# docker run -it --name busybox busybox:latest
/ #
#交互运行容器默认退出后会停止
[root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
838cb22c2314 busybox:latest "sh" 57 seconds ago Exited (130) 15 seconds ago busybox
c08933f2a30a nginx:1.26 "/docker-entrypoint...." 2 minutes ago Up 2 minutes 80/tcp web
#运行停止的容器
[root@docker-node1 ~]# docker start busybox
busybox
[root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
838cb22c2314 busybox:latest "sh" About a minute ago Up 3 seconds busybox
c08933f2a30a nginx:1.26 "/docker-entrypoint...." 2 minutes ago Up 2 minutes 80/tcp web
#退出交互容器不对其停止
[root@docker-node1 ~]# docker attach busybox
/ # read escape sequence # [ctrl]+[p]+[q] #按键
[root@docker-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
838cb22c2314 busybox:latest "sh" 2 minutes ago Up About a minute busybox
c08933f2a30a nginx:1.26 "/docker-entrypoint...." 3 minutes ago Up 3 minutes 80/tcp web
#查看容器信息
[root@docker-node1 ~]# docker inspect busybox
#容器控制
[root@Docker-node1 ~]# docker stop busybox #停止容器
[root@Docker-node1 ~]# docker kill busybox #杀死容器,可以使用信号
[root@Docker-node1 ~]# docker start busybox #开启停止的容器
#在已经运行的容器中执行指定命令
[root@docker-node1 ~]# docker exec busybox touch /root/haha #非交互
[root@docker-node1 ~]# docker exec busybox ls /root
haha
[root@docker-node1 ~]# docker exec -it web /bin/bash #交互的
root@c08933f2a30a:/# exit
exit
#容器删除
[root@docker-node1 ~]# docker rm -f busybox
busybox
[root@docker-node1 ~]# docker stop web
web
[root@docker-node1 ~]# docker rm web
web
#内容提交
[root@docker-node1 ~]# docker run -it --name test busybox:latest
/ # touch /root/file
/ # ls /root/
file
[ctrl]+[p]+[q]
[root@docker-node1 ~]# docker commit -m "add file" test busybox-file:latest
sha256:429465e1ba2297623cba4e806b55b8ec68a66b42d0ed9cca27f17deeea0473aa
[root@docker-node1 ~]# docker images
i Info → U In Use
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
busybox-file:latest 429465e1ba22 6.71MB 2.21MB
busybox:latest b3255e7dfbcd 6.7MB 2.22MB U
nginx:1.26 41b194461e4b 279MB 75.2MB
nginx:latest bc45d248c4e1 237MB 65.8MB
timinglee/game2048:latest 8a34fb9cb168 77.2MB 17.8MB
#文件在镜像中的复制
[root@docker-node1 ~]# docker run -it --name test busybox-file:latest
[root@docker-node1 ~]# docker cp test:/root/file /mnt
Successfully copied 1.54kB to /mnt
[root@docker-node1 ~]# ls /mnt/
file
[root@docker-node1 ~]# docker cp /etc/passwd test:/root/
Successfully copied 3.58kB to test:/root/
[root@docker-node1 ~]# docker exec test ls /root
file
passwd
#创建并启动 mario 容器
[root@docker-node1 ~]# docker run -d --name mario -p 80:8080 timinglee/mario:latest
Unable to find image 'timinglee/mario:latest' locally
latest: Pulling from timinglee/mario
615765bc0d9f: Pull complete
d3be476df650: Pull complete
11b25b5b7583: Pull complete
a3ed95caeb02: Pull complete
911d09728ffd: Pull complete
bbe1c4256df3: Pull complete
Digest: sha256:7758988210dfc2c26d17376171ed8c8e0cb68cb44d9cda06f3382b06304788d9
Status: Downloaded newer image for timinglee/mario:latest
30549dcd8460894b2ce46b80ef5c028bd4295467ae797f3dd091b92ade16ec33
[root@docker-node1 ~]# curl http://localhost:80
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8" />
<title>Full Screen Mario</title>
<meta name="keywords" content="fullscreenmario, full, screen, mario, javascript, html5, gaming, online, online game, fun, distraction" />
<meta name="description" content="FullScreenMario is a free HTML5 remake of Nintendo's original Super Mario Bros. Play it here!" />
<link rel="stylesheet" href="index.min.css">
<link rel="shortcut icon" href="Theme/Mario.gif">
</head>
<body>
<header>
<!-- <img src="Theme/Header.gif" alt="FullScreenMario.com" /> -->
<div id="header-right">
<a class="hoverable" target="_blank" href="https://twitter.com/FullScreenMario">
<img id="twitter" src="Theme/Twitter.png" alt="Twitter" />
</a>
<a class="hoverable" target="_blank" href="https://github.com/FullScreenShenanigans/FullScreenMario">
<img id="github" src="Theme/Github.png" alt="Github" />
</a>
<a class="hoverable" target="_blank" href="https://facebook.com/FullScreenMario">
<img id="facebook" src="Theme/Facebook.png" alt="Facebook" />
</a>
</div>
</header>
<section id="game">
<!-- FSM.UserWrapper will fill out this section... -->
</section>
<section id="controls">
<!-- FSM.UserWrapper will fill out this section... -->
</section>
<div id="explanation" class="section-text">
<pre>
██████╗ ██████╗ ██████╗██╗ ██╗███████╗██████╗ ███████╗██╗ ██╗██████╗ ███████╗██████╗ ███╗ ███╗ █████╗ ██████╗ ██╗ ██████╗
██╔══██╗██╔═══██╗██╔════╝██║ ██╔╝██╔════╝██╔══██╗ ██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗ ████╗ ████║██╔══██╗██╔══██╗██║██╔═══██╗
██║ ██║██║ ██║██║ █████╔╝ █████╗ ██████╔╝ ███████╗██║ ██║██████╔╝█████╗ ██████╔╝ ██╔████╔██║███████║██████╔╝██║██║ ██║
██║ ██║██║ ██║██║ ██╔═██╗ ██╔══╝ ██╔══██╗ ╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗ ██║╚██╔╝██║██╔══██║██╔══██╗██║██║ ██║
██████╔╝╚██████╔╝╚██████╗██║ ██╗███████╗██║ ██║ ███████║╚██████╔╝██║ ███████╗██║ ██║ ██║ ╚═╝ ██║██║ ██║██║ ██║██║╚██████╔╝
╚═════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═════╝
</pre>
<pre>
______ _ _______ _ ___ _ __ _ _
| ___ \ | | ( ) ___ \ | / ( ) | | / / (_) | |
| |_/ /_ ___ _____| | |/| |_/ / |/ /|/ | |/ / __ _ _ __ ___ _ _ __ ___| | ___ _
| __/ _` \ \ / / _ \ | | __/| \ | \ / _` | '_ ` _ \| | '_ \/ __| |/ / | | |
| | | (_| |\ V / __/ | | | | |\ \ | |\ \ (_| | | | | | | | | | \__ \ <| |_| |
\_| \__,_| \_/ \___|_| \_| \_| \_/ \_| \_/\__,_|_| |_| |_|_|_| |_|___/_|\_\\__, |
__/ |
|___/
</pre>
<div>
<script src="FullScreenMario-0.10.1.min.js"></script> <script src="index.min.js"></script>
</body>
</html>
容器镜像构建
#建立构建目录
[root@docker-node1 ~]# mkdir docker
[root@docker-node1 ~]# cd docker/
#编写构建规则文件
[root@docker-node1 docker]# vim Dockerfile
#FROM
FROM busybox:latest
#COPY
[root@docker-node1 docker]# echo timinglee > timinglee
[root@docker-node1 docker]# cat timinglee
timinglee
[root@docker-node1 docker]# vim Dockerfile
FROM busybox:latest
COPY timinglee /root
#构建命令
[root@docker-node1 docker]# docker build -t timinglee:v1 .
[+] Building 0.4s (7/7) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 78B 0.0s
=> [internal] load metadata for docker.io/library/busybox:latest 0.1s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 46B 0.0s
=> [1/2] FROM docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f 0.0s
=> => resolve docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f 0.0s
=> [2/2] COPY timinglee /root 0.0s
=> exporting to image 0.1s
=> => exporting layers 0.0s
=> => exporting manifest sha256:eb144432307d241f7e1fa3edf4ef4e641aa50f0be7329d5b64cd3bc7df1db31c 0.0s
=> => exporting config sha256:299e4926200c368a43c1406d9f81a578bc62c1063d2fc7579aabcbf35ddad093 0.0s
=> => exporting attestation manifest sha256:9bd2ef6b6e85cc3d5051243489e43b0bfc70595c78be0965ed6d2177aacd5e0c 0.0s
=> => exporting manifest list sha256:c42a715ffdf9ceb806c9751c835fa327baa341a09b448d888884cac02 b75221f 0.0s
=> => naming to docker.io/library/timinglee:v1 0.0s
=> => unpacking to docker.io/library/timinglee:v1
#LABEL KEY=VALUES
LABEL creater=lee
#ADD
[root@docker-node1 docker]# echo lee > lee
[root@docker-node1 docker]# vim Dockerfile
FROM busybox:latest
LABEL Creater=lee
COPY timinglee /root
ADD lee /root
[root@docker-node1 docker]# docker build -t lee:v5 .
[+] Building 0.1s (8/8) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 111B 0.0s
=> [internal] load metadata for docker.io/library/busybox:latest 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [1/3] FROM docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f 0.0s
=> => resolve docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 82B 0.0s
=> CACHED [2/3] COPY timinglee /root 0.0s
=> [3/3] ADD lee /root 0.0s
=> exporting to image 0.1s
=> => exporting layers 0.0s
=> => exporting manifest sha256:88332124a66ba662e3f16f6e5d035bb5e0fed31a54e8dedf9aa49d602f131d3b 0.0s
=> => exporting config sha256:9da2fa8f39b3247afee3c2db263560c86602fb8ebfdf517ab069e1aece2569ac 0.0s
=> => exporting attestation manifest sha256:29aa280f165e7c959b57ea7c4cef62aabb6f317d517eb1984ce3e13a85a1e2ca 0.0s
=> => exporting manifest list sha256:ba189de866ec172760df87341d334bd452b35e2f3cafebca4f5ef08121a93519 0.0s
=> => naming to docker.io/library/lee:v5 0.0s
=> => unpacking to docker.io/library/lee:v5
#add可以解压缩COPY不能
FROM busybox:latest
LABEL Creater=lee
COPY bin.tar.gz /root
ADD bin.tar.gz /mnt
#ENV
ENV NAME=timinglee
RUN ["/bin/sh","-c", "touch /root/$NAME" ]
#EXPOSE
EXPOSE 8080
[root@docker-node1 docker]# docker history lee:v5
IMAGE CREATED CREATED BY SIZE COMMENT
ba189de866ec 30 seconds ago ADD lee /root # buildkit 4.1kB buildkit.dockerfile.v0
<missing> 6 minutes ago COPY timinglee /root # buildkit 4.1kB buildkit.dockerfile.v0
<missing> 6 minutes ago LABEL Creater=lee 0B buildkit.dockerfile.v0
<missing> 17 months ago BusyBox 1.37.0 (glibc), Debian 13 4.49MB
#VOLUEM
FROM busybox:latest
LABEL Creater=lee
ENV NAME=timinglee
EXPOSE 8080
VOLUME "/mnt"
RUN ["/bin/sh","-c", "touch /root/$NAME" ]
#测试
[root@docker-node1 docker]# docker build -t lee:v6 .
[+] Building 0.6s (6/6) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 164B 0.0s
=> [internal] load metadata for docker.io/library/busybox:latest 0.1s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> CACHED [1/2] FROM docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd 0.0s
=> => resolve docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f 0.0s
=> [2/2] RUN ["/bin/sh","-c", "touch /root/timinglee" ] 0.4s
=> exporting to image 0.1s
=> => exporting layers 0.0s
=> => exporting manifest sha256:1ef550df7489b270346a335e9f414b64e95f630aa95ddf1d349a02ff62c40fe0 0.0s
=> => exporting config sha256:494cdb75ec66afba61a4661839f7a93c8176a454c3b9be6a46713364857dd5ae 0.0s
=> => exporting attestation manifest sha256:2c26b28e20ae3804280b691892ad0ab6f3394dc4f38c798e7f91025f0d519666 0.0s
=> => exporting manifest list sha256:e8bec3643fffcc1fa9f227d09675e484d8c0e2ba71aeee67b5787ea71ae884d2 0.0s
=> => naming to docker.io/library/lee:v6 0.0s
=> => unpacking to docker.io/library/lee:v6
[root@docker-node1 docker]# docker run -it --name test --rm lee:v6
[root@docker-node1 docker]# docker inspect test | grep -i mounts -A10
"Mounts": [
{
"Type": "volume",
"Name": "928c7eefc0655979354442c347dc0334aad29dde8e5ed8afd9448f07402a1bdc",
"Source": "/var/lib/docker/volumes/928c7eefc0655979354442c347dc0334aad29dde8e5ed8afd9448f07402a1bdc/_data",
"Destination": "/mnt",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
[root@docker-node1 ~]# cd "/var/lib/docker/volumes/951e0ad881eda84a037614657b89cae88adac7c600ac03cd9505c067cee04741/_data"
[root@docker-node1 docker]# touch lee{1..5}
#在容器中
/ # ls /mnt/
lee1 lee2 lee3 lee4 lee5
#WORKDIR
FROM busybox:latest
LABEL Creater=lee
ENV NAME=timinglee
EXPOSE 8080
VOLUME "/mnt"
RUN ["/bin/sh","-c", "touch /root/$NAME" ]
WORKDIR "/mnt"
[root@docker-node1 ~]# docker build -t lee:v7 .
[+] Building 0.1s (7/7) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 189B 0.0s
=> [internal] load metadata for docker.io/library/busybox:latest 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [1/3] FROM docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f 0.0s
=> => resolve docker.io/library/busybox:latest@sha256:b3255e7dfbcd10cb367af0d409747d511aeb66dfac98cf30e97e87e4207dd76f 0.0s
=> CACHED [2/3] RUN ["/bin/sh","-c", "touch /root/timinglee" ] 0.0s
=> CACHED [3/3] WORKDIR /mnt 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => exporting manifest sha256:91866cda152a8cd1522270daac7b8f5deeac0505f79083f0dbdbf28261f969c7 0.0s
=> => exporting config sha256:268e50a154b9414ad0140c0603c752256ca1ef05e29e620602e6496ff28e54c7 0.0s
=> => exporting attestation manifest sha256:e5bfbbc5c840578e1201fca0191bcfd1ae679fdff7e03e1161dea4ce57f13181 0.0s
=> => exporting manifest list sha256:3298d44717572cf8e4ced1720d96246370d7575f4ec8bc6fc2ceb1511d513931 0.0s
=> => naming to docker.io/library/lee:v7 0.0s
=> => unpacking to docker.io/library/lee:v7
[root@docker-node1 docker]# docker run -it --name test --rm lee:v7
/mnt #
#CMD
#ENV CMD
FROM busybox
MAINTAINER lee@timinglee.org
ENV NAME lee
#CMD echo $NAME
#CMD ["/bin/echo", "$NAME"]
CMD ["/bin/sh", "-c", "/bin/echo $NAME"]
[root@Docker-node1 docker]# docker run -it --rm --name test example:v3
lee
[root@Docker-node1 docker]# docker run -it --name test --rm lee:v8 echo haha
haha
#ENTRYPOINT
FROM busybox
MAINTAINER lee@timinglee.org
ENV NAME lee
ENTRYPOINT echo $NAME
[root@Docker-node1 docker]# docker run -it --rm --name test example:v3 sh
lee
[root@docker-node1 docker]# docker run -it --name test --rm lee:v8
timinglee
[root@docker-node1 docker]# docker run -it --name test --rm lee:v8 echo haha
timinglee
镜像优化
方法1.缩减镜像层
[root@docker-node1 ~]# vim Dockerfile
FROM centos:7 AS build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.26 && yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@docker-node1 ~]# docker build -t webserver:v2 .
[root@docker-node1 ~]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v2 caf0f80f2332 4 seconds ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB
方法2.多阶段构建
[root@docker-node1 ~]# vim Dockerfile
FROM centos:7 AS build
ADD nginx-1.26.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.26 && yum clean all
FROM centos:7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@docker-node1 ~]# docker build -t webserver:v3 .
[root@docker-node1 ~]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v3 1ac964f2cefe 29 seconds ago 205MB
webserver v2 caf0f80f2332 3 minutes ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB
方法3.使用最精简镜像
使用google提供的最精简镜像
下载地址:
https://github.com/GoogleContainerTools/distroless
下载镜像:
docker pull gcr.io/distroless/base
利用最精简镜像构建
[root@docker-node1 ~]# mkdir new
[root@docker-node1 ~]# cd new/
[root@docker-node1 ~]# vim Dockerfile
FROM nginx:1.23 AS base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG TIME_ZONE
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /usr/sbin/nginx-debug /opt && \
cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libpcre* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime
FROM gcr.io/distroless/base-debian11
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
[root@docker-node1 ~]# docker build -t webserver:v4 .
[root@docker-node1 ~]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v4 c0c4e1d49f3d 4 seconds ago 34MB
webserver v3 1ac964f2cefe 12 minutes ago 205MB
webserver v2 caf0f80f2332 15 minutes ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB