K8S - 从零构建 Docker 镜像与容器
一、基础概念
1.1 镜像(Image)
“软件的标准化安装包” ,包含代码、环境和配置的只读模板。
技术解析
镜像由多个层组成,每层对应一个Dockerfile指令:
应用代码 → 运行时环境 → 系统工具链 → 启动配置
核心特性
-
分层存储(每层对应 Dockerfile指令)
-
内容寻址(SHA256 哈希防篡改)
-
不可变性(构建后无法修改)
1.2 容器(Container)
“镜像的运行时实例,基于镜像创建的独立进程,像轻量级隔离的进程沙箱”。
技术解析
容器实例化后,会添加可写层,并应用进程隔离与资源限制机制:
镜像 → 可写层 → 进程隔离(Namespace)→ 资源限制(Cgroups)
核心能力
-
进程隔离(Linux Namespaces)
-
资源限制(CPU/内存配额 Cgroups)
-
临时存储(OverlayFS可写层)
1.3 Dockerfile
“镜像的构建说明书”,以 文本文件形式定义如何组装镜像。
技术解析
FROM python:3.8-slim # 选择基础镜像
WORKDIR /app # 设置工作目录
COPY requirements.txt .
RUN pip install -r requirements.txt # 安装依赖
COPY . . # 复制应用代码
CMD ["python", "app.py"] # 设置默认启动命令
关键原则
-
指令顺序影响构建效率
-
每个 RUN 生成新层(可合并命令减少层数)
核心价值
1.4 概念关系图
Dockerfile → (docker build) → 镜像 → (docker run) → 容器 → (修改) → 可写层
可写层 -x (容器删除) → 数据丢失
二、 构建第一个镜像
1.环境准备(Mac/Win/Linux通用)
# 安装Docker
# 官网下载:https://www.docker.com/products/docker-desktop
# 验证安装
docker --version
# 预期输出示例:Docker version 20.10.17, build 100c701
2. 示例代码
项目结构概览
my-first-image/ # 项目根目录
│── app.py # Flask 应用主程序
│── requirements.txt # Python 依赖文件
│── Dockerfile # 构建镜像的 Dockerfile
步骤1:创建项目文件
app.py
# 新建项目目录
mkdir ~/my-first-image && cd ~/my-first-image# 创建Python应用文件
cat <<EOF > app.py
from flask import Flask
app = Flask(__name__)@app.route('/')
def hello():return "Hello, 这是我的第一个容器!"if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)
EOF# 生成依赖文件
echo "Flask==2.2.2" > requirements.txt
requirements.txt
Flask==2.2.2
步骤2:编写 Dockerfile (基础版,单阶段)
# 使用官方Python轻量版镜像
FROM python:3.8-slim# 设置容器内工作目录(自动创建)
WORKDIR /app# 1. 先复制依赖文件(利用缓存优化)
COPY requirements.txt .# 2. 安装依赖
RUN pip install --no-cache-dir -r requirements.txt# 3. 复制应用代码
COPY . .# 声明容器监听端口(实际映射需通过-p参数)
EXPOSE 5000# 容器启动命令(JSON格式避免shell解析问题)
CMD ["python", "app.py"]
步骤3:构建镜像
# 构建镜像(注意最后的点 . )
docker build -t my-first-app:v1 .# 查看生成的镜像
docker images
预期输出示例:REPOSITORY TAG IMAGE ID SIZE
my-first-app v1 a1b2c3d4e5 123MB
步骤4:运行容器
# 启动容器(前台运行,便于调试)
docker run -p 8000:5000 my-first-app:v1# 新开终端,测试访问:
curl http://localhost:8000
# 或在浏览器访问:http://localhost:8000
预期输出:
Hello, 这是我的第一个容器!
关键说明:
-
缓存优化:先单独复制 requirements.txt安装依赖,代码变更时避免重复安装。
-
–no-cache-dir:禁用 pip缓存,减少镜像体积。
-
EXPOSE:仅为文档说明,实际端口映射需通过 -p 8000:5000实现。
三、Dockerfile实践与高效构建
3.1 Dockerfile 三大核心特性
特性1:分层构建(Layer)
title 镜像层组成
"基础镜像"
"依赖安装"
"应用代码"
"元数据"
缓存机制:重复构建时未变化的层直接复用缓存。
特性2:声明式语法
Dockerfile 示例
FROM python:3.8-slim # 声明环境
COPY . /app # 声明文件
CMD ["python", "app.py"] # 声明启动
特点:描述 “做什么”而非 “怎么做”。
特性3:跨平台一致性
-
构建结果与宿主机环境无关
-
相同 Dockerfile 在任何平台生成相同镜像
3.2 核心指令解析
Dockerfile 基础指令集 (结合第二章示例)
指令说明
FROM :必须是 Dockerfile 的第一条有效指令。
最佳实践:
• 选择官方维护的基础镜像(如 python:3.8-slim)
• 避免使用 未经审计的第三方镜像
• -slim或 alpine版本可减少镜像体积
WORKDIR
• 会自动创建目录(如果不存在)。
• 比 RUN cd /app && … 更规范。
COPY
• 比 ADD 更推荐使用(除非需要自动解压功能)。
• 受 .dockerignore 文件影响。
RUN
• 每个 RUN 指令都会创建一个新的镜像层。
• 建议合并相关命令(如 apt-get update && apt-get install)。
CMD
生产环境建议
3.3 基础镜像选择指南
1. 官方镜像仓库推荐
# 通用搜索语法(所有语言适用)
docker search --filter "is-official=true" [技术栈关键词]# 示例:
docker search --filter "is-official=true" node
docker search --filter "is-official=true" golang
官方镜像特征:
• 命名规范:[技术栈]:[版本]-[变体]
# 标准格式示例:
docker pull node:18-bullseye-slim # Node.js 官方镜像
docker pull golang:1.20-alpine # Go 官方镜像
docker pull nginx:1.25-alpine # Nginx 官方镜像
2. 主流语言推荐基础镜像
| 语言 | 开发环境镜像 | 生产环境镜像 |
|------------|---------------------|-------------------------|
| Python | `python:3.10` | `python:3.10-slim` |
| Node.js | `node:18` | `node:18-alpine` |
| Java | `eclipse-temurin:17`| `eclipse-temurin:17-jre`|
3. 镜像变体对比
A[镜像变体] --> B[完整版]
A --> C[精简版]
A --> D[最小版]
B -->|含gcc/make等| E[500MB+]
C -->|仅运行时依赖| F[100-300MB]
D -->|musl libc| G[5-50MB]
选择原则
### 选择原则(新手友好版)
1. 生产环境优先选择 `-slim` 或 `-alpine````bash# 正确示例docker pull python:3.10-slim
# 开发调试 使用完整版, 临时使用(勿用于生产)
docker pull python:3.10
常用命令
# 查看镜像架构
docker manifest inspect python:3.9 | grep architecture# 拉取指定平台镜像
docker pull --platform=linux/amd64 nginx:alpine
3.4 容器生命周期管理命令集
1. 镜像管理命令
# 构建镜像(注意最后的点表示当前目录)
docker build -t myapp:v1 .# 查看镜像列表(grep 过滤)
docker images | grep python# 查看镜像构建历史
docker history myapp:v1# 删除镜像(-f 强制删除)
docker rmi -f myapp:v1# 给镜像打标签
docker tag myapp:v1 registry.example.com/myapp:v1# 推送镜像到仓库
docker push registry.example.com/myapp:v1
2. 容器操作命令
创建与启动# 创建并运行容器(-d 后台运行,-p 端口映射)
docker run -d -p 8080:80 --name mynginx nginx:alpine# 只创建不运行容器
docker create --name my_redis redis:6# 启动已创建的容器
docker start my_redis
运行中管理
# 查看运行中的容器(-a 显示所有,-q 只显示 ID)
docker ps -a
docker ps -q# 进入容器交互模式(推荐 /bin/sh,更轻量)
docker exec -it mynginx /bin/sh# 查看实时日志(--tail 显示最后 N 行)
docker logs -f --tail=100 mynginx
停止与删除# 优雅停止容器(发送 SIGTERM)
docker stop mynginx# 强制停止容器(发送 SIGKILL)
docker kill my_redis# 删除容器(-f 强制删除运行中的容器)
docker rm -f mynginx
3. 系统管理命令# 查看容器资源使用(CPU/内存/网络)
docker stats# 查看容器详细信息
docker inspect mynginx# 宿主机和容器之间拷贝文件
docker cp ./local_file mynginx:/container_path
docker cp mynginx:/container_path ./local_dir
4. 一键清理命令
# 清理所有停止的容器(-f 强制)
docker container prune -f# 清理所有悬空镜像
docker image prune -f# 彻底清理(包括未使用的镜像和缓存)
docker system prune -a
5. 生产环境组合命令
# 批量停止并删除所有容器
docker stop $(docker ps -aq) && docker rm $(docker ps -aq)# 删除所有 <none> 镜像(悬空镜像)
docker rmi $(docker images -f "dangling=true" -q)# 重启所有容器(先 stop 再 start)
docker stop $(docker ps -q) && docker start $(docker ps -aq)
6. 注意事项# 重要数据必须挂载 volume(示例)
docker run -v /host/path:/container/path mysql# 设置资源限制(示例)
docker run --memory="1g" --cpus="2" myapp# 使用非 root 用户运行(在 Dockerfile 中添加)
RUN useradd -m appuser && chown -R appuser /app
USER appuser
四、总结
4.1 核心概念关系
A[Dockerfile] --> B[镜像]
B --> C[容器]
C --> D[Pod]
D --> E[Deployment]