资讯动态

Linux系统下Docker安装与核心概念实战指南

发布时间:2026/8/6 1:22:19 来源:尧图企业网站定制
1. 从“为什么需要Docker”开始聊起如果你在Linux服务器上折腾过软件部署大概率经历过这样的场景为了部署一个应用你需要先安装特定版本的Python然后安装一堆依赖包结果发现某个依赖包和系统里另一个服务的依赖版本冲突导致整个环境崩掉。或者你在一台Ubuntu 22.04上跑得好好的服务迁移到CentOS 7上就各种报错光是排查环境差异就耗掉大半天。这种“在我机器上能跑”的困境是每个运维和开发者都头疼的问题。Docker的出现就是为了解决这个核心痛点。它不是一个轻量级的虚拟机而是一个容器化技术。你可以把它理解为一个超级轻便、标准化的“软件集装箱”。这个集装箱里打包了你的应用代码、运行环境、系统工具、系统库和设置。无论这个集装箱被运到哪台支持Docker的Linux机器上我们称之为“宿主机”它都能以完全一致的方式运行起来。这彻底解决了环境不一致的问题让开发、测试、生产环境的部署变得极其简单和可靠。我最早接触Docker是在一个微服务项目里当时十几个服务每个服务的依赖环境都不同手动部署简直是噩梦。自从用上Docker所有服务的环境都被固化在镜像里通过一个简单的docker-compose up命令就能拉起整个集群部署时间从几小时缩短到几分钟。这种效率的提升是革命性的。所以无论你是想学习一项热门技术还是切实想提升自己的开发和部署效率掌握Linux下的Docker都是非常值得投入时间的一步。2. 安装前的准备理清思路与避坑指南在动手安装Docker之前有几个关键点必须搞清楚这能帮你避开后面90%的坑。很多人一上来就照着教程敲命令结果遇到各种“virtualization support not detected”或者权限问题其实根源都在准备阶段没做好。首先明确你的Linux发行版和版本。Docker对主流发行版的支持都很好但安装方式略有不同。最常见的是基于Debian的如Ubuntu、Debian和基于RPM的如CentOS、RHEL、Fedora。你需要用cat /etc/os-release命令确认一下。这篇文章的实操部分会以Ubuntu 22.04 LTS和CentOS 7这两个最典型的系统为例进行讲解其他发行版可以举一反三。其次理解Docker的架构和核心概念。Docker采用的是客户端-服务器C/S架构。我们平时在命令行里敲的docker命令其实是Docker客户端Client。它通过REST API与一个常驻后台进程通信这个后台进程就是Docker守护进程Daemon它负责创建、运行和管理容器。我们安装Docker主要就是安装这个守护进程、客户端以及相关的工具链。最后也是最重要的检查系统环境。这里有两个大坑内核版本Docker需要较新的Linux内核来支持其底层特性如cgroups、namespaces。对于生产环境建议内核版本在3.10以上。用uname -r查看。存储驱动Docker镜像和容器数据需要存储驱动来管理。对于较新的发行版默认的overlay2驱动是首选性能最好。但有些旧系统或云主机可能用了devicemapper这可能会带来性能问题。安装后需要确认。注意网上很多教程会提到要“开启虚拟化支持”这通常是针对在Windows或macOS上安装Docker Desktop时的要求。在纯Linux环境下安装Docker Engine也就是我们常说的Docker并不需要CPU的虚拟化技术如Intel VT-x/AMD-V。Docker容器直接共享宿主机内核利用的是Linux内核的cgroup和namespace等特性来实现隔离这与虚拟机VM的硬件虚拟化是完全不同的技术路线。所以如果你在Linux主机上遇到类似“virtualization support not detected”的错误提示那很可能是你错误地尝试安装Docker Desktop for Linux或者混淆了概念。在Linux上我们安装的是原生的Docker Engine。3. Ubuntu 22.04 系统下的Docker安装详解Ubuntu是个人学习和开发环境中使用最广泛的Linux发行版其软件包管理工具apt非常方便。下面我们走一遍最稳妥的安装流程我会解释每一步的作用。3.1 卸载旧版本与配置仓库第一步永远是清理战场避免旧版本残留导致冲突。即使你是新系统执行一下也无妨。sudo apt-get remove docker docker-engine docker.io containerd runc这条命令移除了可能存在的旧版Docker包。containerd和runc是Docker依赖的底层容器运行时我们后续会安装更新的版本。接下来我们需要让apt知道从哪里获取Docker官方软件包。Docker官方维护了一个APT仓库比Ubuntu自带源中的版本更新、更稳定。# 更新apt包索引并安装一些工具这些工具允许apt通过HTTPS使用仓库 sudo apt-get update sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release # 添加Docker官方的GPG密钥。GPG密钥用于验证软件包的签名确保你下载的包是官方发布的没有被篡改。 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 设置稳定版仓库。这里将仓库地址写入/etc/apt/sources.list.d/docker.list文件。 echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null这里有个细节$(lsb_release -cs)会自动获取你的Ubuntu代号比如jammy对应22.04。这确保了仓库地址与你的系统版本匹配。3.2 安装Docker Engine仓库配置好后安装就很简单了。# 再次更新apt包索引这次它会读取我们刚添加的Docker仓库信息。 sudo apt-get update # 安装Docker Engine、命令行工具cli、containerd以及docker-compose-plugin。 # 注意包名是docker-ce社区版docker-ee是企业版。 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin执行这个命令后apt会自动处理所有依赖。安装完成后Docker守护进程会自动启动。3.3 验证安装与权限配置安装是否成功跑一个最经典的测试镜像就知道了。sudo docker run hello-world如果看到“Hello from Docker!”等欢迎信息说明Docker已经成功安装并可以拉取和运行容器了。但每次命令都要加sudo很麻烦而且有安全风险。通常我们会将当前用户加入docker用户组这样就能直接执行docker命令。# 创建docker用户组通常安装时已自动创建 sudo groupadd docker # 将当前用户加入docker组 sudo usermod -aG docker $USER关键一步退出当前终端并重新登录或者新开一个终端用户组的更改才会生效。之后你就可以不用sudo直接运行docker ps等命令了。验证一下docker run --rm ubuntu:22.04 /bin/echo Hello, Docker!能成功输出信息说明权限配置正确。4. CentOS 7 系统下的Docker安装与差异点处理CentOS 7以及RHEL 7在企业服务器中非常常见但它的内核版本相对较老且使用yum作为包管理器安装过程与Ubuntu有显著区别。4.1 清理环境与添加仓库CentOS的Extras仓库提供了一个旧版本的docker包实际上是docker.io但版本非常老旧我们一定要先卸载它然后使用Docker官方仓库。# 卸载旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine # 安装yum工具包它提供了yum-config-manager工具用于管理仓库。 sudo yum install -y yum-utils # 添加Docker官方仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo4.2 安装Docker Engine及可能的内核升级CentOS 7默认内核是3.10虽然满足Docker的最低要求但某些新特性可能不支持。如果条件允许建议升级到更新的内核如ELRepo仓库的长期支持版内核。这里我们先按默认内核安装。# 安装Docker Engine sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin如果安装过程中提示container-selinux版本冲突这是因为Docker依赖的container-selinux版本高于CentOS默认仓库提供的。你需要从CentOS Extras仓库安装一个特定版本或者先安装centos-release-extras包。一个常见的解决命令是sudo yum install -y https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-version.rpm # 然后再安装docker-ce具体版本号需要去Docker仓库查看。这是CentOS 7安装Docker时最常见的坑。4.3 启动服务与配置防火墙CentOS使用systemd管理服务且默认开启了防火墙firewalld需要额外配置。# 启动Docker守护进程 sudo systemctl start docker # 设置开机自启 sudo systemctl enable docker # 验证安装 sudo docker run hello-world防火墙配置Docker守护进程默认会创建一个docker0的网桥容器通过它进行网络通信。为了让容器能与外界或宿主机正常通信需要在防火墙中放行相关流量。# 永久放行Docker服务使用的端口范围默认是2375/2376但通常我们不用 # 更常见的做法是信任docker0网桥的流量 sudo firewall-cmd --permanent --zonetrusted --add-interfacedocker0 sudo firewall-cmd --reload如果你在容器内运行了Web服务如映射了80端口还需要在防火墙中放行对应的宿主机端口sudo firewall-cmd --permanent --add-port80/tcp sudo firewall-cmd --reload同样记得将用户加入docker组以避免sudosudo groupadd docker sudo usermod -aG docker $USER # 重新登录后生效5. Docker核心概念与基础命令实战安装好了我们来真正用起来。要熟练使用Docker必须理解三个核心概念镜像Image、容器Container、仓库Registry。它们的关系就像面向对象编程中的类和对象。镜像Image一个只读的模板里面包含了运行应用所需的代码、库、环境变量和配置文件。它相当于一个“类”的定义。例如ubuntu:22.04,nginx:latest,python:3.9-slim。容器Container镜像的一个运行实例。你可以创建、启动、停止、删除容器。容器与容器之间是相互隔离的。它相当于根据“类”创建出来的一个“对象”。仓库Registry集中存放镜像的地方。最大的公共仓库是 Docker Hub 你可以从这里拉取镜像也可以推送自己的镜像上去。私有的仓库可以自己搭建比如用Harbor。下面是一组你最需要掌握的基础命令我附上了实际使用场景和解释。5.1 镜像相关操作# 从仓库拉取镜像。如果不指定标签默认拉取 latest。 # 建议生产环境总是指定明确的版本标签避免因latest更新导致意外。 docker pull nginx:1.23-alpine # 列出本地已下载的镜像 docker images # 或者使用更强大的新命令 docker image ls docker image ls # 搜索Docker Hub上的镜像通常直接去网站搜更直观 docker search mysql # 删除本地镜像。如果镜像有对应的容器即使已停止需要先删除容器才能删除镜像。 # 使用 -f 可以强制删除但慎用。 docker rmi nginx:1.23-alpine # 删除所有未被容器使用的镜像悬空镜像 docker image prune # 删除所有未被使用的镜像包括未被任何容器引用的镜像 docker image prune -a5.2 容器生命周期管理这是最核心的部分容器就像一个轻量级的进程。# 运行一个容器 # -d: 后台运行detached mode # --name mynginx: 给容器起个名字否则Docker会随机分配一个 # -p 8080:80: 端口映射将宿主机的8080端口映射到容器的80端口 # nginx:alpine: 使用的镜像 docker run -d --name mynginx -p 8080:80 nginx:alpine # 此时在浏览器访问 http://你的服务器IP:8080就能看到Nginx欢迎页。 # 列出正在运行的容器 docker ps # 列出所有容器包括已停止的 docker ps -a # 停止一个运行中的容器 docker stop mynginx # 启动一个已停止的容器 docker start mynginx # 重启容器 docker restart mynginx # 进入一个正在运行的容器的命令行终端 # -it 是 -i (交互式) 和 -t (分配一个伪终端) 的组合让你可以像SSH一样操作容器。 docker exec -it mynginx /bin/sh # 对于基于Alpine的镜像shell通常是/bin/sh对于Ubuntu等是/bin/bash。 # 查看容器的日志输出排查问题非常有用 docker logs mynginx # 实时查看日志类似 tail -f docker logs -f mynginx # 删除一个已停止的容器 docker rm mynginx # 强制删除一个运行中的容器不推荐应先停止 docker rm -f mynginx # 删除所有已停止的容器清理空间 docker container prune5.3 容器与宿主机的数据交互容器默认是“无状态”的其内部文件系统的改动在容器删除后会丢失。为了持久化数据如数据库文件、配置文件、日志我们需要使用卷Volume或绑定挂载Bind Mount。卷Volume由Docker管理存储在宿主机文件系统的某个区域通常是/var/lib/docker/volumes/与容器的生命周期解耦。这是持久化数据的推荐方式。# 创建一个名为 my-vol 的卷 docker volume create my-vol # 运行容器并使用这个卷将容器内的 /app/data 目录挂载到卷上 docker run -d --name myapp -v my-vol:/app/data myapp-image # 即使 myapp 容器被删除my-vol 卷及其数据依然存在可以被其他容器挂载。绑定挂载Bind Mount将宿主机上的一个特定目录或文件直接挂载到容器中。常用于开发环境方便在宿主机上修改代码容器内实时生效。# 将宿主机的 /home/user/project 目录挂载到容器的 /app 目录 docker run -d --name dev-app -v /home/user/project:/app dev-app-image # 现在你在宿主机上修改代码容器内的 /app 下文件也会同步变化。6. 使用Dockerfile定制专属镜像从公共镜像仓库拉取镜像很方便但更多时候我们需要构建自己的镜像比如部署自己的Python应用、Java应用。这就需要编写Dockerfile。Dockerfile是一个文本文件包含了一条条构建镜像所需的指令。下面我们以一个简单的Python Flask应用为例手把手构建一个镜像。项目结构myflaskapp/ ├── app.py ├── requirements.txt └── Dockerfileapp.py(一个最简单的Flask应用)from flask import Flask app Flask(__name__) app.route(/) def hello(): return Hello, Docker! if __name__ __main__: app.run(host0.0.0.0, port5000)requirements.txtFlask2.3.2Dockerfile# 第一阶段使用官方Python轻量级镜像作为构建环境 FROM python:3.9-slim as builder # 设置工作目录后续命令都在这个目录下执行 WORKDIR /app # 将依赖文件复制到工作目录 COPY requirements.txt . # 安装依赖。使用清华PyPI镜像加速并将依赖安装到 /usr/local RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt # 第二阶段使用更小的运行时镜像只复制必要的文件 FROM python:3.9-slim # 设置工作目录 WORKDIR /app # 从构建阶段复制已安装的Python包 COPY --frombuilder /usr/local /usr/local # 复制应用代码 COPY . . # 声明容器运行时监听的端口 EXPOSE 5000 # 定义容器启动时执行的命令 CMD [python, app.py]逐行解释FROM: 指定基础镜像。我们使用了两阶段构建第一阶段builder用于安装依赖第二阶段使用同一个基础镜像但只复制安装结果可以显著减小最终镜像体积。WORKDIR: 设置工作目录相当于cd到这个目录。COPY: 将宿主机文件复制到镜像内。RUN: 在构建镜像时执行的命令这里用来安装依赖。我们使用了国内镜像源加速下载。EXPOSE: 声明容器打算使用的端口这是一个文档性质的说明实际端口映射需要在docker run时用-p指定。CMD: 指定容器启动时默认执行的命令。一个Dockerfile中只能有一条CMD指令。构建镜像 在myflaskapp目录下执行# -t 给镜像打标签格式为 名称:标签标签默认为 latest # . 表示Dockerfile所在的当前目录为构建上下文 docker build -t my-flask-app:1.0 .运行容器# 将宿主机的5000端口映射到容器的5000端口 docker run -d --name myapp -p 5000:5000 my-flask-app:1.0访问http://localhost:5000就能看到“Hello, Docker!”了。7. 使用Docker Compose编排多容器应用现实中的应用很少是单个容器通常由多个服务组成比如一个Web应用需要搭配数据库、缓存等。手动用docker run启动每一个容器并配置网络链接非常繁琐。Docker Compose就是用来定义和运行多容器Docker应用的工具。它使用一个YAML文件默认docker-compose.yml来配置所有服务。假设我们有一个WordPress博客需要WordPress容器和MySQL数据库容器。创建一个docker-compose.yml文件version: 3.8 # 指定Compose文件格式版本 services: # 数据库服务 db: image: mysql:8.0 # 容器重启策略除非手动停止否则总是重启 restart: always environment: # 设置MySQL的root密码和环境变量这是必须的 MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress # 命名卷用于持久化数据库数据 volumes: - db_data:/var/lib/mysql # 自定义网络让服务间可以通过服务名通信 networks: - wp-network # WordPress服务 wordpress: depends_on: - db # 声明依赖确保db服务先启动 image: wordpress:latest restart: always ports: - 8080:80 # 将宿主机的8080端口映射到WordPress容器的80端口 environment: # 告诉WordPress如何连接数据库这里db就是上面定义的服务名 WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_DB_NAME: wordpress volumes: # 绑定挂载将当前目录下的wp-content目录挂载方便主题/插件管理 - ./wp-content:/var/www/html/wp-content networks: - wp-network # 定义卷Docker Compose会自动创建和管理它 volumes: db_data: # 定义网络Docker Compose会自动创建一个名为项目名_wp-network的网络 networks: wp-network: driver: bridge运行与管理 在包含docker-compose.yml的目录下执行以下命令# 启动所有服务后台运行 docker-compose up -d # 查看服务状态 docker-compose ps # 查看所有服务的日志 docker-compose logs # 查看特定服务如wordpress的日志 docker-compose logs wordpress # 停止所有服务 docker-compose stop # 停止并删除所有容器、网络但保留卷 docker-compose down # 停止并删除所有容器、网络、卷数据也会被删除 docker-compose down -vDocker Compose极大地简化了多服务应用的部署和管理是开发测试环境的利器。对于更复杂的生产环境集群编排则需要用到Kubernetes (K8s)或Docker Swarm。8. 生产环境部署的进阶考量与优化将Docker用于个人学习或开发很简单但一旦要上生产环境就需要考虑更多因素安全性、性能、日志、监控、镜像仓库等。1. 镜像优化与安全扫描使用多阶段构建如上文Flask例子所示可以大幅减小最终镜像体积减少攻击面。使用特定标签不要使用latest标签而应使用明确的版本号如python:3.9.16-slim-bullseye。使用非root用户运行容器在Dockerfile中创建并使用非root用户。RUN groupadd -r appuser useradd -r -g appuser appuser USER appuser定期扫描镜像漏洞可以使用docker scan命令集成Snyk或第三方工具如Trivy、Clair扫描镜像中的已知安全漏洞。2. 日志管理容器默认将日志输出到stdout和stderrDocker守护进程会捕获并存储。在生产环境中需要将日志集中收集和管理。使用日志驱动可以配置Docker守护进程将日志发送到json-file默认、syslog、journald或fluentd等。使用Docker Compose的logging配置可以限制日志文件大小防止磁盘被撑满。services: myapp: image: myapp logging: driver: json-file options: max-size: 10m max-file: 33. 资源限制防止单个容器耗尽宿主机资源。# 运行容器时限制CPU和内存 docker run -d --name myapp \ --cpus1.5 \ # 限制使用1.5个CPU核心 --memory512m \ # 限制内存为512MB --memory-swap1g \ # 限制内存交换分区总量为1GB myapp-image4. 使用私有镜像仓库生产环境不应直接从Docker Hub拉取镜像。应该搭建私有仓库如Harbor、Nexus或使用云服务商提供的仓库如ACR、ECR、GCR。登录私有仓库docker login myregistry.example.com给镜像打上私有仓库标签docker tag myapp:1.0 myregistry.example.com/myapp:1.0推送镜像docker push myregistry.example.com/myapp:1.0拉取镜像docker pull myregistry.example.com/myapp:1.05. 服务发现与网络对于多主机集群Docker原生的bridge网络不够用。需要结合Overlay网络Swarm模式或直接使用Kubernetes的CNI容器网络接口插件来管理跨主机的容器网络。从单机安装到多容器编排再到生产环境的考量Docker的学习路径是循序渐进的。我个人的经验是先在本机或虚拟机里把单容器和Docker Compose玩熟练理解镜像、容器、数据卷、网络这些核心概念。当你的应用变得复杂需要高可用、自动伸缩时再去探索Kubernetes的世界。Docker是这一切的基石扎实的基础会让你后续的学习轻松很多。在实际操作中最常遇到的坑往往是权限问题Got permission denied、端口冲突、镜像拉取慢记得配置国内镜像加速器以及磁盘空间不足记得定期prune。多动手多查日志解决问题的过程本身就是最好的学习。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价