当前位置: 首页 > news >正文

【Linux从入门到精通】第35篇:容器化技术预备——Docker安装与基本概念

一、引言:为什么需要Docker?

还记得第2篇我们安装Linux环境时用了虚拟机吗?虚拟机确实解决了“一台电脑跑多个系统”的问题,但它有三大痛点:

  1. :每个虚拟机都要跑一个完整的操作系统内核,启动要几十秒,占用几个GB的磁盘

  2. :虚拟机的资源是预先分配的,不管实际用不用,分配的CPU和内存都得占着,资源利用率不高

  3. ** “我这里能跑啊” **:开发环境里正常运行的应用,到了测试环境就各种报错——“依赖版本不对”“系统库缺失”“配置文件路径不一样”

Docker的解决方案很巧妙:不再笨拙地模拟整个硬件和操作系统,而是让所有容器共享宿主机的操作系统内核,只是在用户空间上做隔离

Docker vs 虚拟机

对比维度虚拟机Docker容器
启动速度几十秒到几分钟毫秒到秒级
磁盘占用每个VM几个GB镜像通常几十到几百MB
资源利用率预先分配,浪费多按需使用,共享宿主
隔离级别完全操作系统隔离进程级隔离(共享内核)
可移植性受虚拟化平台限制任何装了Docker的系统都能跑

Docker的三大核心价值

  • 环境一致性:开发、测试、生产用同一个镜像,“这里能跑”不再是问题

  • 轻量化:共享宿主内核,秒级启动,一台服务器能运行几十上百个容器

  • 可复现构建:Dockerfile描述构建步骤,任何人都能复现一模一样的镜像

二、核心概念:镜像、容器、仓库

Docker有三个核心概念,理解它们的关系是入门的关键。

2.1 镜像

镜像可以类比为:一个软件的“安装文件”或“快照”。它包含了运行某个应用所需的一切——代码、运行时、系统库、环境变量、配置文件。

关键特性:镜像是只读的、分层的。当你修改镜像时,Docker不会改动原有层,而是在上面叠加新的一层。这种设计让不同镜像可以共享相同的基础层,极大节省磁盘空间。

2.2 容器

容器可以类比为:运行起来的“进程实例”。容器就是镜像的运行态。

关键特性:容器是可读写的——Docker在镜像的只读层上加了一个读写层,你在容器中的所有操作(写文件、装软件)都发生在这个读写层。容器删除,读写层也随之消失。

镜像和容器的关系,就像程序和进程的关系(第11篇的概念!):

  • 镜像是静态的定义(程序)

  • 容器是动态的运行实例(进程)

  • 同一个镜像可以启动多个互相隔离的容器

2.3 仓库

仓库可以类比为:镜像的“GitHub”。Docker Hub是默认的公共仓库,里面有官方维护的Nginx、MySQL、Python等镜像,也有社区贡献的各种镜像。

关键操作:docker pull nginx就是把Nginx镜像从仓库拉取到本地;docker push myname/myimage就是把你自己的镜像推送上去。

2.4 一张图理清三者关系

text

docker pull → 从仓库下载镜像到本地 docker run → 从本地镜像启动容器 docker build → 用Dockerfile把应用打包成镜像 docker push → 把本地镜像上传到仓库

三者关系也可以简单总结为:从仓库下载镜像,用镜像启动容器,把容器打包成新镜像,再将镜像上传到仓库。整个Docker生态就是围绕这个闭环运转的。

三、Docker快速上手

3.1 安装Docker

Docker官方提供了一键安装脚本(适合快速体验,生产环境建议用发行版官方源):

bash

# Ubuntu/Debian curl -fsSL https://get.docker.com | sudo bash # 将当前用户加入docker组(省去每次sudo) sudo usermod -aG docker $USER # 退出重新登录后生效

验证安装:

bash

docker --version docker run hello-world

如果看到Hello from Docker!的欢迎信息,说明安装成功。

3.2 docker run:启动你的第一个容器

bash

# 启动一个Nginx容器 docker run -d --name my-nginx -p 8080:80 nginx

参数拆解

参数含义
-d后台运行(detached mode)
--name my-nginx给容器命名,方便后续操作
-p 8080:80端口映射:将宿主8080端口映射到容器80端口
nginx使用的镜像名(本地没有会自动拉取)

验证:

bash

curl http://localhost:8080 # 看到Nginx欢迎页面的HTML内容

3.3 docker ps:查看运行中的容器

bash

docker ps # 只看运行中的 docker ps -a # 包括已停止的

输出解读:

text

CONTAINER ID IMAGE STATUS PORTS NAMES a1b2c3d4e5f6 nginx Up 10 minutes 0.0.0.0:8080->80/tcp my-nginx
  • CONTAINER ID:容器的唯一标识(可以只用前几位来操作)

  • STATUS:容器当前状态

  • PORTS:端口映射关系

3.4 docker exec:进入容器的“门”

bash

# 进入容器内部,启动bash交互式环境 docker exec -it my-nginx bash

参数拆解:

  • -i:交互模式,保持标准输入打开

  • -t:分配一个伪终端

  • my-nginx:容器名(也可以用容器ID)

  • bash:要执行的命令

进入容器后,你就等于在这台“微型Linux”里操作了,可以查看配置、调试问题,就像SSH进了另一台机器一样:

bash

# 在容器内部 ls /etc/nginx/ cat /usr/share/nginx/html/index.html # 这就是Nginx欢迎页的源文件 exit # 退出容器

3.5 容器的生命周期管理

命令作用类比
docker start 容器名启动已停止的容器开机
docker stop 容器名停止运行中的容器关机
docker restart 容器名重启容器重启
docker rm 容器名删除已停止的容器卸载(需先stop)
docker rm -f 容器名强制删除(包括运行中的)强制卸载

重要docker rm只能删除已停止的容器。要删除运行中的容器,先docker stopdocker rm,或用docker rm -f直接强制删除。

3.6 查看日志

bash

# 查看容器日志 docker logs my-nginx # 实时跟踪 docker logs -f my-nginx

四、实战:将应用打包成Docker镜像

下面我们将一个简单的Python Web应用打包成Docker镜像。

4.1 准备应用代码

bash

mkdir myapp && cd myapp

创建app.py

python

from flask import Flask import os app = Flask(__name__) @app.route('/') def hello(): host = os.uname().nodename return f'Hello Docker! (hostname: {host})' if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

创建requirements.txt

text

flask

4.2 编写Dockerfile

Dockerfile是一个描述了“如何构建这个镜像”的指令文件:

dockerfile

# 1. 基础镜像:从官方Python镜像开始 FROM python:3.10-slim # 2. 设置工作目录 WORKDIR /app # 3. 复制依赖文件并安装 COPY requirements.txt . RUN pip install -r requirements.txt # 4. 复制应用代码 COPY app.py . # 5. 声明容器监听的端口(仅声明,实际映射在运行时指定) EXPOSE 5000 # 6. 容器启动时执行的命令 CMD ["python", "app.py"]

逐条解释

  • FROM:基础镜像,所有后续操作都在它的基础上叠加

  • WORKDIR:设置工作目录,后续命令和CMD都以此为基础

  • COPY:从宿主机复制文件到镜像中

  • RUN:在镜像构建时执行命令(安装依赖等)

  • EXPOSE:文档性质的端口声明,真正的端口映射需要运行时的-p参数

  • CMD:容器启动时默认执行的命令

4.3 构建镜像

bash

docker build -t myapp:v1 .
  • -t myapp:v1:给镜像打标签,myapp是名称,v1是版本

  • .:表示Dockerfile在当前目录

输出会显示每一步的执行过程(Step 1/6 → Step 2/6 ...)。

4.4 运行容器

bash

docker run -d --name myapp-container -p 5000:5000 myapp:v1

验证:

bash

curl http://localhost:5000 # 输出:Hello Docker! (hostname: <容器ID>)

4.5 查看与管理镜像

bash

# 查看本地所有镜像 docker images # 删除镜像(需先删除关联的所有容器) docker rmi myapp:v1 # 给镜像打新标签 docker tag myapp:v1 myapp:latest

五、Docker常用命令速查

类别命令作用
镜像docker images查看本地镜像
镜像docker pull nginx:1.25从仓库拉取镜像(1.25指定版本,不加则默认latest)
镜像docker build -t name:tag .用Dockerfile构建镜像
镜像docker rmi 镜像名删除镜像
容器docker run -d --name xxx -p 宿:容 镜像启动新容器
容器docker ps/docker ps -a查看运行中/所有容器
容器docker exec -it 容器名 bash进入容器
容器docker start/stop/restart 容器名启动/停止/重启容器
容器docker rm 容器名删除容器
容器docker logs -f 容器名跟踪查看日志

六、本篇小结

核心概念金三角

  • 镜像:构建一次,到处运行(相当于二进制可执行文件)

  • 容器:镜像的运行实例,隔离但共享内核

  • 仓库:镜像的存储和分发中心

最小化上手流程

bash

docker run hello-world # 验证安装 docker run -d --name web -p 80:80 nginx # 后台启动Nginx docker ps # 查看状态 docker exec -it web bash # 进入容器探索

构建自己的应用镜像

bash

# 1. 写Dockerfile(FROM + COPY + RUN + CMD) # 2. docker build -t app:v1 . # 3. docker run -d -p 端口:端口 app:v1

动手练习

bash

# 1. 验证Docker安装 docker run hello-world # 2. 启动Nginx容器并验证 docker run -d --name test-nginx -p 8088:80 nginx curl http://localhost:8088 # 3. 进入容器看看Nginx的文件结构 docker exec -it test-nginx bash # 在容器内:cat /usr/share/nginx/html/index.html # 退出:exit # 4. 停止并删除容器 docker stop test-nginx docker rm test-nginx # 5. 构建自己的应用镜像 mkdir ~/docker-test && cd ~/docker-test # 按第四节的方法创建app.py、requirements.txt、Dockerfile # docker build -t myapp:v1 . # docker run -d --name myapp -p 5000:5000 myapp:v1 # curl http://localhost:5000

常见问题排查

端口已被占用

text

Error: port is already allocated

换一个宿主机端口:-p 8081:80(宿主的8081映射到容器的80)。

镜像拉取失败

text

Error response from daemon: pull access denied

检查镜像名是否正确,国内环境可配置镜像加速器(阿里云容器镜像服务提供免费加速器),配置方法搜索“Docker镜像加速”。

七、下篇预告

掌握了Docker的基本操作,下一篇我们将探索Linux中另一个重要的网络服务——DNS。DNS是互联网的“电话簿”,下一篇我们将自己搭建一个内网DNS服务器,实现局域网内的域名解析,甚至可以劫持广告域名来屏蔽广告请求。


延伸思考:Docker的“一次构建,到处运行”听起来完美,但实际中仍有“坑”——latest标签在不同时间拉取的镜像版本可能完全不同。生产环境推荐的做法是锁定具体版本(如nginx:1.25.3),确保所有环境跑的是完全相同的镜像。版本固定,才能让“可复现”真正落地。

http://www.jsqmd.com/news/730492/

相关文章:

  • 从“像素误差”到“结构感知”:SSIM如何重塑了我们对图像质量的认知?
  • Autovisor:当Python Playwright遇上智慧树,自动化学习不再是梦
  • 如何解决LenovoLegionToolkit启动异常:WMI接口故障终极指南
  • 大语言模型微调实战:从LoRA原理到ChatGPT定制化应用
  • nftables 规则的原子化更新
  • 中之网:构建“官网+短视频+AI大模型”全域营销矩阵,抢占电机行业智能搜索新蓝海
  • Excel高效使用技巧(五):效率倍增工具:宏/VBA入门与自动化场景实战
  • 别再让RS485模块偷电了!STM32低功耗项目实测与外围电路功耗优化指南
  • 2026年南京青少年心理咨询医院选择指南与服务解析 - 品牌排行榜
  • Bili2text:3步将B站视频转为文字稿,开启高效学习新篇章
  • ComfyUI-Manager终极指南:AI绘画插件一键管理,彻底告别安装烦恼
  • 2026年水果店加盟哪家靠谱?行业从业者经验分享 - 品牌排行榜
  • 终极Windows权限解锁指南:如何用RunAsTI获取TrustedInstaller系统最高权限
  • Excel插件:随机抽奖(抽签)
  • 2026年3月有名的冲孔加工生产厂家口碑推荐,防火软接/冲孔加工/消音冲孔板,冲孔加工生产厂家选哪家 - 品牌推荐师
  • 【R核心团队内部技术简报解密】:R 4.5 spatial stack重构原理、ABI兼容边界与2024 Q3必升关键提示
  • 2026年南京焦虑症心理咨询医院选择指南 - 品牌排行榜
  • 2026水果店加盟哪家好?从供应链到体验的全方位对比 - 品牌排行榜
  • 选购教师 D 类机构的技巧,师璞教师有优势吗? - mypinpai
  • Python高级应用系列(二十)Python高级特性全景总结与最佳实践
  • GitHub 热门项目 `modded-nanogpt` 实测:把“90 秒训练 124M”搬到 RTX 3090 后,先炸的不是显存,而是 Hopper 专用内核
  • 2026年3月叫号系统源头厂家推荐,叫号系统/医院排队叫号系统,叫号系统机构口碑推荐 - 品牌推荐师
  • 视觉计时器:解码视频中的物理时间密码
  • Krita-AI-Diffusion插件中文翻译功能的技术实现与架构解析
  • Dify 2026边缘节点安全加固白皮书:FIPS 140-3认证路径、TEE可信执行环境集成及国密SM4动态密钥轮转实现
  • 2026国内评价高的宠物美容培训学校排行:派霏尔实力解析 - 品牌排行榜
  • 房价预测:从线性回想到决策树
  • AI黑箱问题威胁人类尊严
  • 2026医养结合设计公司专业服务与行业实践探讨 - 品牌排行榜
  • 南京情绪障碍心理医院服务指南:专业机构选择与解析 - 品牌排行榜