【容器技术-Docker】Docker镜像

Docker镜像


一、基础入门:理解核心概念

1.1 什么是Docker镜像?
  • 定义:一个轻量级、可执行的独立软件包,包含运行某软件所需的所有内容(代码、运行时、库、环境变量、配置文件)。
  • 与容器的关系:镜像是静态的模板,容器是镜像的运行实例(可读写层)。
  • 分层结构:镜像由多个只读层(Layer)叠加组成,每一层代表一个Dockerfile指令。
1.2 核心概念
  • Dockerfile:构建镜像的自动化脚本,包含一系列指令(FROM, RUN, COPY, CMD等)。
  • Registry:镜像仓库(如Docker Hub, Harbor, AWS ECR),用于存储和分发镜像。
  • Tag :镜像的版本标识(如nginx:1.21)。
  • Base Image :基础镜像,通常是操作系统或语言运行时(如ubuntu:22.04, node:18-alpine)。
1.3 推荐学习资源

二、镜像构建:从Dockerfile到高效镜像

2.1 Dockerfile最佳实践
  • 减少层数 :合并RUN命令(&&连接),使用.dockerignore排除无用文件。
  • 使用多阶段构建:分离构建环境和运行环境,大幅减小镜像体积。
  • 选择合适的基础镜像:优先使用Alpine(5MB左右)或slim版本,避免臃肿的完整系统。
  • 缓存利用:将变化少的指令(如安装依赖)放在前面,变化多的(如COPY代码)放在后面。
2.2 示例:Node.js应用多阶段构建
dockerfile 复制代码
# 第一阶段:构建
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 第二阶段:运行
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/index.js"]
2.3 推荐学习资源

三、镜像管理:存储、分发与安全

3.1 镜像仓库操作
  • 推送/拉取docker push/pull <image>,需先登录(docker login)。
  • 私有仓库:部署Harbor或使用云服务(AWS ECR, Azure Container Registry)。
  • 镜像标签docker tag <source> <target>,用于重命名或标记版本。
3.2 镜像安全
  • 漏洞扫描 :使用docker scan(集成Snyk)或Trivy(开源)。
  • 签名与验证:Docker Content Trust(DCT)或Notary。
  • 最小权限原则 :避免以root运行容器,使用USER指令。
3.3 推荐学习资源

四、进阶主题:镜像优化与调试

4.1 镜像体积优化
  • Alpine vs Debian:Alpine体积小但兼容性可能差(musl libc),Debian slim是折中方案。
  • 清理缓存apt-get cleannpm cache clean --force
  • 压缩工具docker-slim(自动分析并瘦身镜像)。
4.2 镜像调试
  • 进入运行中容器docker exec -it <container> sh
  • 查看镜像历史docker history <image>
  • 导出镜像为文件docker save -o <file>.tar <image>(用于离线传输)。
4.3 推荐学习资源

五、实战项目:从零构建完整镜像

5.1 项目示例1:配置SSH镜像

项目背景:官方下载的centos镜像默认不带ssh,管理起来不方便,自己制作一个带SSH功能的

centos镜像

创建dockerfile

bash 复制代码
[root@docker ~]# vim centos.ssh.dockerfile
FROM centos:8.4.2105
MAINTAINER Harvy
RUN minorver=8.4.2105 && \
sed -e "s|^mirrorlist=|#mirrorlist=|g" \
-e "s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://mirrors.aliyun.com/centos-vault/$minorver|g" \
-i.bak \
/etc/yum.repos.d/CentOS-*.repo
RUN yum install -y openssh-server
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
RUN echo "root:huawei" | chpasswd
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]

构建镜像

bash 复制代码
[root@docker ~]# docker build -t centos:ssh -f centos.ssh.dockerfile .
[+] Building 0.6s (10/10) FINISHED
docker:default
=> [internal] load build definition from centos.ssh.dockerfile
0.0s
=> => transferring dockerfile: 604B
0.0s
=> [internal] load metadata for docker.io/library/centos:8.4.2105
0.0s
=> [internal] load .dockerignore
0.0s
=> => transferring context: 2B
0.0s
=> [1/6] FROM docker.io/library/centos:8.4.2105
0.0s
=> CACHED [2/6] RUN minorver=8.4.2105 && sed -e "s|^mirrorlist=|#mirrorlist=|g"
-e "s|^#baseurl=http://mirror.centos.org/$contentdir/$releasever|baseurl=h 0.0s
=> CACHED [3/6] RUN yum install -y openssh-server
0.0s
=> CACHED [4/6] RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
0.0s
=> [5/6] RUN ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key
0.3s
=> [6/6] RUN echo "root:huawei" | chpasswd
0.3s
=> exporting to image
0.0s
=> => exporting layers
0.0s
=> => writing image
sha256:cc138c4d3c36fe82eab32dd80549707c8bfe99ddcb6d3882319a10283bb1a864
0.0s
=> => naming to docker.io/library/centos:ssh

查看现象

bash 复制代码
[root@docker ~]# docker history centos:ssh
IMAGE CREATED CREATED BY
SIZE COMMENT
cc138c4d3c36 36 seconds ago CMD ["/usr/sbin/sshd" "-D"]
0B buildkit.dockerfile.v0
<missing> 36 seconds ago EXPOSE map[22/tcp:{}]
0B buildkit.dockerfile.v0
<missing> 36 seconds ago RUN /bin/sh -c echo "root:huawei" | chpasswd...
1.77kB buildkit.dockerfile.v0
<missing> 36 seconds ago RUN /bin/sh -c ssh-keygen -t ecdsa -f /etc/s...
695B buildkit.dockerfile.v0
<missing> 47 minutes ago RUN /bin/sh -c ssh-keygen -t rsa -f /etc/ssh...
3.18kB buildkit.dockerfile.v0
<missing> 47 minutes ago RUN /bin/sh -c yum install -y openssh-server...
51.9MB buildkit.dockerfile.v0
<missing> About an hour ago RUN /bin/sh -c minorver=8.4.2105 && sed -e "...
17.6kB buildkit.dockerfile.v0
<missing> About an hour ago MAINTAINER Harvy
0B buildkit.dockerfile.v0
<missing> 3 years ago /bin/sh -c #(nop) CMD ["/bin/bash"]
0B
<missing> 3 years ago /bin/sh -c #(nop) LABEL org.label-schema.sc...
0B
<missing> 3 years ago /bin/sh -c #(nop) ADD file:805cb5e15fb6e0bb0...
231MB

测试

bash 复制代码
#基于刚才dockerfile创建的镜像centos:ssh创建容器sshtest
[root@docker ~]# docker run -d -p 2022:22 --name sshtest centos:ssh
73d963d15407a1e73097540bb320b9edf05b468001bd707abf01bc7be5e54bcb
#创建出来的容器
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
73d963d15407 centos:ssh "/usr/sbin/sshd -D" 6 seconds ago Up 5 seconds
0.0.0.0:2022->22/tcp, :::2022->22/tcp sshtest
#ssh登录容器测试ssh,能够成功登录
[root@docker ~]# ssh root@localhost -p 2022
The authenticity of host '[localhost]:2022 ([::1]:2022)' can't be established.
ECDSA key fingerprint is SHA256:z1owYLOuClnbPrZwXxgy1jcItQT1k+QX6LxosydT64A.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[localhost]:2022' (ECDSA) to the list of known hosts.
root@localhost's password:
"System is booting up. Unprivileged users are not permitted to log in yet. Please
come back later. For technical details, see pam_nologin(8)."
[root@73d963d15407 ~]#
5.2 项目示例2:自定义httpd镜像

创建dockerfile

bash 复制代码
# 提前在工作目录下创建index.html
[root@docker ~]# vim httpd.dockerfile
FROM centos:8.4.2105
MAINTAINER gaoqiaodong
RUN minorver=8.4.2105 \
&& sed -e "s|^mirrorlist=|#mirrorlist=|g" -e
"s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://m
irrors.aliyun.com/centos-vault/$minorver|g" -i.bak /etc/yum.repos.d/CentOS-*.repo
RUN yum install -y httpd && yum clean all && rm -rf /var/cache/yum
COPY index.html /var/www/html/
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]

构建镜像

bash 复制代码
[root@docker ~]# docker build -t httpd:centos -f httpd.dockerfile .

查看现象

bash 复制代码
[root@docker ~]# docker history httpd:centos

测试

bash 复制代码
#基于刚才dockerfile创建的镜像httpd:centos创建容器myweb
[root@docker ~]# docker run -d -p 80:80 --name myweb httpd:centos
1e0b0631cf708bcc0a162d56b936a12cd06c9bcdebcc2594b23c2fbee3ed8894
#创建出来的容器
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
1e0b0631cf70 httpd:centos "/usr/sbin/httpd -DF..." About a minute ago Up
About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp myweb
#访问测试
5.3 推荐学习资源

六、常见问题与故障排查

问题 原因 解决方案
镜像体积过大 未使用多阶段构建或基础镜像过大 改用Alpine/slim,合并RUN命令
构建缓存失效 COPY代码层变化导致后续层全部重建 先COPY依赖文件,再COPY源码
容器启动失败 CMD/ENTRYPOINT路径错误或缺少依赖 使用docker logs查看错误日志
镜像漏洞多 基础镜像未更新或包含未使用组件 定期扫描,使用最小化基础镜像

七、学习路径总结

  1. 第1周 :理解镜像分层原理,掌握docker builddocker pull等基础命令。
  2. 第2周:编写Dockerfile,实践多阶段构建和体积优化。
  3. 第3周:学习镜像仓库操作(推送/拉取),部署私有仓库。
  4. 第4周:集成安全扫描(Trivy),学习镜像签名和验证。
  5. 第5周:参与开源项目或自建项目,将镜像构建集成到CI/CD流水线。

八、推荐工具与资源汇总

  • 学习平台:Docker官方文档、Play with Docker(已废弃)、Katacoda(已停更,但仍有存档)。
  • 书籍:《Docker in Action》(第二版)、《The Docker Book》。
  • 社区:Docker官方论坛、Reddit r/docker、Stack Overflow。
  • 监控工具:Docker Desktop Dashboard、Portainer(可视化管理)。
相关推荐
诸葛老刘1 小时前
在PC机上 使用docker vLLM镜像部署Qwen3-1.7B
docker·vllm
飞飞传输1 小时前
内外网文件交换系统产品推荐:高密网低密网摆渡更安全高效
大数据·运维·安全
Waay1 小时前
Linux Shell 知识点考评(二):sed 流编辑器(附答案)
linux·运维·服务器
请叫我徐先生1 小时前
seafile 在飞牛下 docker 部署重启设备后 seahub 异常无法启动的解决方案
docker·debian·seafile·飞牛·fnos
brevity_souls1 小时前
SQL server格式化日期
运维·服务器·数据库
大肥羊学校懒羊羊1 小时前
FAST-LIVO2 一键复现教程(Ubuntu 20.04 / ROS Noetic )
linux·运维·ubuntu
郝亚军1 小时前
libmodbus在Ubuntu 22.04上按arm64架构编译方法
linux·运维·ubuntu
IT布道1 小时前
[Git] 源码服务器主/备备份方案
运维·服务器·git
China_Yanhy1 小时前
AWS RDS PostgreSQL 大版本升级故障复盘与 SRE 最佳实践指南
运维·云计算·aws