镜像(image)、容器(container)、docker、Dockerfile
永久存储,构成镜像。
定义

https://support.huaweicloud.com/bestpractice-ecs/zh-cn_topic_0141067581.html
镜像是只读的
永久存储,构成镜像
容器是可写的
容器删除后即消失。
容器是操作系统内核自带能力,是基于Linux内核实现的轻量级高性能资源隔离机制。
为什么需要使用容器
- 更高效的利用系统资源。
容器不需要硬件虚拟化以及运行完整操作系统等额外开销,所以对系统资源利用率更高。相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
- 更快速的启动时间。
- 一致的运行环境。
- 更轻松地迁移、维护和扩展。
容器确保了执行环境的一致性,使得应用迁移更加容易。同时使用的存储及镜像技术,使应用重复部分的复用更为容易,基于基础镜像进一步扩展镜像也变得非常简单。
https://support.huaweicloud.com/bestpractice-cce/cce_bestpractice_0002.html
分层设计
核心优势
资源共享与节省磁盘空间
假设你有两个镜像:
• my-app:python (基于 python:3.9 ) • my-app:node (基于 node:16 )
如果你的主机上已经拉取了 python:3.9 和 node:16 ,那么这两个镜像的底层(操作系统层等)可能是共享的。当你拉取 my-app:python 时,Docker 只会下载它独有的层,而不会重复下载已经存在的 python:3.9 的层。这极大地节省了磁盘空间和网络带宽。
高速构建(利用构建缓存)
Docker 在构建镜像时会使用缓存。它会检查 Dockerfile 中的每一条指令:
- 如果指令和之前构建时完全一样,并且生成该指令的层的父层也没有变化,Docker 就会直接使用缓存中已有的层,而不会重新执行该指令。
最佳实践:为了最大化利用缓存,应该将变化频率低的指令放在 Dockerfile 的前面(如安装依赖),将变化频率高的指令放在后面(如复制源代码)。
减少分层
在满足可维护性和缓存效率的前提下,尽量减少不必要的层数。
通过合理的指令合并,优化Dockerfile结构,以最大化利用构建缓存,同时保持代码的可读性和可维护性。
简化管理和可追溯性(重要原因)
- 一个拥有50层的镜像比一个拥有10层的镜像更难理解和调试。使用 docker history 命令查看时,过多的、细碎的层会让构建过程变得不清晰。合并相关的指令(如多个 RUN 指令)可以使Dockerfile的逻辑更清晰,更易于维护。
合并RUN指令
使用 .dockerignore 文件
在构建时,避免将不必要的文件(如 node_modules , .git 目录)复制到构建上下文中,因为 COPY 或 ADD 指令会检查文件变化,无关文件的变化会导致缓存失效。
选择合适的基础镜像
使用更小、更精简的基础镜像(如 Alpine Linux 变体)可以显著减小最终镜像的大小。
推荐写法举例
平衡层数与缓存效率
FROM ubuntu:20.04
# 首先,将变化频率低、耗时长的操作放在前面
RUN apt-get update && \
apt-get install -y curl python3 git
# 注意:这里清理了apt缓存,有助于减小镜像体积
&& rm -rf /var/lib/apt/lists/*
# 然后,再复制源代码等变化频繁的文件
COPY requirements.txt /tmp/requirements.txt
RUN pip install -r /tmp/requirements.txt
# 最后,复制剩余的源代码
COPY . /app
docker
常用命令
# 列出本地主机上所有已下载的 Docker 镜像
docker images
# 只显示镜像ID,常用于批量操作
docker images -q
# 拉取最新的 Ubuntu 镜像
docker pull ubuntu
# 拉取指定标签的 Nginx 镜像(例如 1.21 版本)
docker pull nginx:1.21
# 搜索名为 mysql 的镜像
docker search mysql
# 删除指定ID的镜像
docker rmi <image_id>
# 强制删除镜像(即使有容器正在使用它)
docker rmi -f <image_id>
# 删除所有镜像
docker rmi $(docker images -q)
# 使用当前目录的 Dockerfile 构建一个名为 my-app 版本为 v1 的镜像
docker build -t my-app:v1 .
# 查看正在运行的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 显示所有容器的ID
docker ps -aq
运行容器相关命令
# 交互式运行一个 Ubuntu 容器,并进入其 bash shell
docker run -it ubuntu /bin/bash
# 在后台运行一个 Nginx 容器,并将主机的 8080 端口映射到容器的 80 端口
docker run -d --name my-nginx -p 8080:80 nginx
# 运行一个容器,挂载数据卷,并在退出后自动删除
docker run --rm -v /host/data:/container/data alpine ls /container/data
# 启动、停止、重启一个或多个已存在的容器
docker start <container_id_or_name>
docker stop <container_id_or_name> # 优雅地停止
docker restart <container_id_or_name>
# 在名为 my-nginx 的容器中执行 `ls` 命令
docker exec my-nginx ls /etc/nginx
# 以交互模式进入容器(非常常用!)
docker exec -it my-nginx /bin/bash
# 查看容器日志
docker logs <container_id_or_name>
# 实时查看日志
docker logs -f <container_id_or_name>
# 查看最后10行日志并实时跟踪
docker logs --tail 10 -f <container_id_or_name>
# 删除指定容器
docker rm <container_id_or_name>
# 强制删除容器(即使正在运行)
docker rm -f <container_id_or_name>
# 删除所有已停止的容器(清理空间的神器)
docker container prune
# 或者使用旧语法
docker rm $(docker ps -aq)
# 查看容器的所有详细信息
docker inspect <container_id_or_name>
# 使用 --format 过滤信息,例如只查看 IP 地址
docker inspect --format='{{.NetworkSettings.IPAddress}}' <container_id_or_name>
Dockerfile
编写高效的Dockerfile
https://support.huaweicloud.com/bestpractice-swr/swr_bestpractice_0002.html
更多推荐

所有评论(0)