ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Docker快速开始:从安装部署到MySQL与Redis容器实战指南

Docker快速开始:从安装部署到MySQL与Redis容器实战指南 拿 Docker 快速开始这个标题来说网上教程一抓一大把但大部分都卡在装完 Docker Desktop 就不知道怎么往下走这个环节。要么是安装报错直接把人劝退要么是跑起来之后完全不懂容器和镜像的关系遇到 MySQL 起不来、网络不通、权限拒绝这类问题只能干瞪眼。这篇东西我打算换个写法直接从新手最常见的真实场景切入把安装、踩坑、跑通第一个容器、部署 MySQL 和 Redis、排查日常故障这几件事串成一条完整的链路命令直接给理由也讲清楚。先说清楚一个容易误导人的概念Docker 不是虚拟机。很多第一次接触的人会以为 Docker 是那种装一个操作系统镜像启动一个完整系统的东西这是错的。Docker 里的容器共享宿主机内核只是把进程、文件系统、网络、环境变量隔离在各自的命名空间里所以一个容器往往只有几十 MB 到几百 MB启动时间以毫秒级计算同样一台机器能跑的容器数量和虚拟机完全不是一个量级。这也是为什么有人能用 N100 这种低功耗小主机跑二十个 Docker 容器——每个容器本身就只是几个进程而已而不是二十个操作系统。1.1 容器和虚拟机的本质区别判断自己到底有没有理解容器可以问一个问题容器里的 Ubuntu 有内核吗答案是没有。你执行uname -r看到的其实是宿主机的内核版本。容器镜像里携带的是 rootfs根文件系统和用户态的程序比如 bash、glibc、MySQL 服务本身内核用的是宿主机的。这带来的直接后果是容器天然轻量、启动快、资源占用低但也意味着容器里不能随便改内核参数、不能加载内核模块遇到依赖特定内核版本的应用会比较尴尬。虚拟机就不一样每个虚拟机都有独立的 Guest OS有自己完整的内核隔离性更强但启动要几十秒到几分钟镜像动辄几个 GB运行时要预分配内存和 CPU。所以 Docker 适合微服务、CI/CD、应用打包交付VM 适合需要强隔离、跨内核的场景。这俩不是替代关系但在快速开始这个语境下Docker 确实是当下部署应用最主流的姿势。1.2 Docker 解决的核心痛点结合热搜词里docker是干什么的这个问题我用一句大白话回答Docker 让你的应用打包一次到处运行。以前部署一个 MySQL你得下载安装包、处理依赖库、配配置文件、设系统服务到了另一台机器这套流程要再来一遍。用 Docker 之后镜像里已经把 MySQL 和它需要的一切都打包好了你只需要docker run服务就起来了。开发环境、测试环境、生产环境全都用同一个镜像杜绝了在我电脑上是好的这种甩锅现场。另外 Docker 还解决了环境隔离和快速清理的问题。想装一个 GitLab、装一个青龙面板、跑一个 DVWA 靶场练手直接拉官方镜像跑起来不用了就docker rm -f删掉宿主机干干净净不会像传统安装方式那样留下一堆残留文件。2. 安装 Docker 之前需要搞明白的三件事安装本身不难但很多报错其实是安装前的平台理解出了问题。这里把三个关键决策点说透能避开后面 80% 的坑。2.1 你的系统平台决定了走哪条安装路线Docker 的安装方式基本分成两大流派带图形界面的 Docker Desktop适合 Windows 和 macOS以及纯命令行安装 Docker Engine适合 Linux 服务器。Windows 装 Docker Desktop 需要 WSL2 或 Hyper-V 支持Mac 上有 Apple Silicon 和 Intel 两种芯片的区分Linux 又分为 apt/yum/dnf 不同包管理器。选错路线最常见的后果就是装完了启动不了然后陷入virtualization support not detected这类报错循环。如果你用的是 Ubuntu 或者 CentOS 这类 Linux 服务器就直接装 Docker Engine不要装 Docker Desktop。Docker Engine 就是服务器上跑的守护进程dockerd加客户端docker CLI没有 GUI但对服务器部署来说完全够用。Ubuntu 走 aptCentOS 7 走 yumCentOS 8 以上走 dnf。具体命令我放到后面先记住一个原则服务器环境永远优先 Docker Engine桌面环境图省事才选 Docker Desktop。2.2 Windows 用户绕不开的 WSL2 / Hyper-V 前置Windows 装 Docker Desktop 的报错里出现频率最高的就是 Docker Desktop failed to start because virtualisation support wasnt detected也就是热搜词里反复出现的那条。这不是 Docker 本身的问题而是 Windows 的虚拟化功能没开全。Docker Desktop 在 Windows 上需要虚拟机支持来跑 Linux 容器这个能力来自 WSL2 或者 Hyper-V。排查链路应该是这样的第一步打开任务管理器 - 性能 - CPU看右下角虚拟化是否显示已启用。如果显示已启用说明 BIOS 层面的虚拟化是开着的如果显示已禁用需要进 BIOS 开启 Intel VT-x 或 AMD SVM。注意Windows 的虚拟化是否启用除了 BIOS还取决于启用 Windows 功能里的虚拟机平台和 Hyper-V 有没有勾上。第二步以管理员身份打开 PowerShell执行wsl --status查看 WSL 版本如果提示没有 WSL需要先安装 WSL2执行wsl --install即可。第三步确认 Windows 功能里适用于 Linux 的 Windows 子系统和虚拟机平台这两项都是勾选状态然后用bcdedit /set hypervisorlaunchtype auto确保 Hyper-V 启动类型是自动。我见过大量案例BIOS 虚拟化开着、WSL 也装了Docker Desktop 还是启动失败最后发现是虚拟机平台这个功能没开。这三步必须挨个排查任何一环断了Docker Desktop 都起不来。2.3 Linux 用户最稳的 Docker Engine 安装路径Linux 安装 Docker Engine 的方式里最推荐的是配置官方 apt 源后安装。以 Ubuntu 为例安装基础工具和证书sudo apt-get update sudo apt-get install ca-certificates curl gnupg lsb-release然后添加 Docker 官方 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 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更新索引后直接安装sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin安装完成后执行sudo systemctl enable docker sudo systemctl start docker再用sudo docker run hello-world验证。为什么不用一条 curl 脚本装官方那个get.docker.com的一键脚本适合快速实验但生产环境我建议手动加源安装因为后续换镜像源、升级版本时路径更清晰也方便排查问题。CentOS 7 的坑主要是默认的 yum 源里 Docker 版本太老必须用官方源或阿里云源不然装出来的可能还是 Docker 1.13。3. Docker Desktop 安装实战与启动失败排查Docker Desktop 是 Windows 和 macOS 上最容易上手的方式但也是报错重灾区。这里把完整的安装流程和两类高频启动失败问题的排查链路写出来照做就行。3.1 Windows 和 macOS 的安装步骤详解Windows 的安装流程比 Linux 复杂完整步骤是开启 Windows 功能控制面板 - 程序 - 启用或关闭 Windows 功能勾选适用于 Linux 的 Windows 子系统、虚拟机平台、Hyper-V三项其中完整版 Docker Desktop 依赖 Hyper-VWSL2 模式下只依赖前两项。安装 WSL2 内核执行wsl --update更新内核然后执行wsl --set-default-version 2确保以后创建的发行版默认走 WSL2。从 Docker 官网下载 Docker Desktop Installer.exe双击安装安装过程中如果提示是否使用 WSL2选“是”。安装完成后重启系统启动 Docker Desktop等右下角鲸鱼图标变稳定状态。macOS 的步骤类似从官网下载 Docker.dmg 拖入 Applications 即可。Apple SiliconM1/M2/M3芯片的 Mac 默认走虚拟化框架不需要额外装虚拟机软件Intel 芯片的老 Mac 需要确认是否支持 HyperKit不过 Docker Desktop 新版已经统一用 Apple 的 Virtualization.framework这点基本不用操心了。注意下 Mac 需要 macOS 11 Big Sur 或更高版本太老的系统装不上新版的 Docker Desktop。3.2 virtualization support not detected报错的完整排查链路这条报错几乎天天有人问完整排查思路按优先级排列第一步确认 BIOS 虚拟化开关。重启进 BIOS找 Intel Virtualization Technology 或 SVM Mode设为 Enabled。注意有些品牌机的 BIOS 里这个选项叫法不同比如 Dell 叫 VirtualizationHP 叫 Virtualization Technology联想部分机型要在 Security - Virtualization 里开。第二步确认 Windows 功能。执行systeminfo | findstr Hyper-V如果显示 Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed. 说明 Hyper-V 已经在跑如果显示 Virtualization Enabled In Firmware: Yes说明固件虚拟化正常但 Hyper-V 组件可能没装。这时去启用或关闭 Windows 功能里勾上虚拟机平台和Hyper-V。第三步核对 WSL2 状态。执行wsl -l -v如果版本显示为 1需要wsl --set-version 发行版名 2升级。如果提示没有已安装的发行版用wsl --install -d Ubuntu装一个。第四步检查 Docker Desktop 的配置。打开 Settings - General确保勾选了 Use the WSL 2 based engine。如果用的是 Hyper-V 模式在 Settings - Resources - Advanced 里确认没有把内存设置得太低。这套链路走完至少能解决 95% 的启动失败。剩下的情况多半是 Windows 老版本的问题比如 Win10 的 1903 以下版本对 WSL2 支持不完整建议直接升级系统。3.3 failed to start docker application container engine的原因与处理这条报错常见于 Linux 上 Docker 服务启动失败以及在 Windows 上 Docker Desktop 已经能打开但内部引擎没跑起来。Linux 下先执行sudo systemctl status docker看具体失败原因。最常见的是配置了镜像加速器地址但写错了格式或者/etc/docker/daemon.json文件里的 JSON 语法错误导致 dockerd 启动崩掉。排查方法是先移走配置文件再启动sudo mv /etc/docker/daemon.json /etc/docker/daemon.json.bak sudo systemctl start docker如果这样启动了说明问题出在 daemon.json。重新编辑时注意配置格式镜像加速地址要加上https://前缀多个地址用数组。Windows 下的同类问题多数是退出 Docker Desktop 后重新启动、彻底重置 WSL 的 Docker 数据来解决不要一上来就卸载重装先试wsl --shutdown再启动 Docker Desktop成功率很高。4. 第一次跑容器的完整流程从 hello-world 到 Nginx安装完 Docker接下来的流程才是快速开始的意义所在。这一节带你走一遍完整的验证环境 - 拉镜像 - 跑容器 - 操作容器链路。4.1 用 docker info 和 hello-world 验证环境是否真正可用装好 Docker 后第一件事不是急着部署应用而是确认环境正常。执行docker info如果看到Server Version和Storage Driver都正常显示说明 dockerd 守护进程在跑。如果看到ERROR: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock这是热搜词里的另一个高频问题说明当前用户不在 docker 用户组里执行sudo usermod -aG docker $USER然后注销重登或重启系统。然后跑官方提供的测试镜像docker run hello-world这个镜像很小只有几 KB作用是打印一段说明文字表示 Docker 端到端工作正常。如果你在服务器上没有 sudo 权限记得所有 docker 命令前加 sudo如果你已经加入了 docker 用户组可以不用 sudo。这里提醒一句能用用户组解决就不要用 sudo 执行 docker 命令sudo 会把文件权限搞得很难受而且在某些自动化的脚本环境里容易出现鸡生蛋问题。4.2 拉取镜像和运行容器Nginx 实例拆解hello-world 只是验证真正跑一个有实际意义的服务用 Nginx 最合适。先把镜像拉到本地docker pull nginx:latestdocker pull的动作是拉镜像镜像是什么本质上是一层一层的只读文件系统的集合里面包含了 Nginx 的程序文件、配置文件、依赖库。拉下来之后本地会有这份镜像缓存下次docker run直接用本地镜像不会再去远程仓库拉。然后启动一个前台运行用于观察输出或者后台运行daemonized的容器docker run -d --name my-nginx -p 8080:80 nginx命令拆解-d表示后台运行--name my-nginx给容器起名-p 8080:80把宿主机的 8080 端口映射到容器内的 80 端口nginx是要运行的镜像名。映射端口的逻辑很多人第一次犯迷糊记住一句话左边是宿主机端口右边是容器内端口。浏览器访问http://localhost:8080宿主机把流量转发给容器里的 80 端口Nginx 接收之后返回默认页面。验证容器状态docker ps如果能看到一个状态为 Up 的 my-nginx 容器说明第一个真实服务已经跑起来了。这条命令的意义相当于进程管理器的 Docker 版列出所有正在运行的容器它只显示运行中的容器已经停止的用docker ps -a查看。两者之间的差别是新手最容易忽略的docker ps -a会把停止状态的容器也列出来排查问题的时候永远先用-a看全貌。4.3 进入容器内部查看文件系统与日志跑起来之后你需要具备的三种最基本的观察能力查看容器日志docker logs my-nginx这一步对应的是传统方式下 tail 日志文件的习惯。docker logs会把容器的 stdout/stderr 全部打出来所以平时写应用时记得把日志打到 stdout而不是写到容器内的日志文件里——否则用docker logs看什么都是空的。进入容器内部docker exec -it my-nginx bashexec表示在运行中的容器里执行命令-it是分配交互终端bash是要执行的 shell。进去之后执行ls /usr/share/nginx/html就能看到 Nginx 默认网页的存放位置。这个能力对应的是传统方式下 SSH 到服务器上排查但在容器里你没有 systemd、没有 init 进程也没有完整系统工具包很多命令不存在是很正常的事别慌。退出用exit。把宿主机的文件复制进容器docker cp index.html my-nginx:/usr/share/nginx/html/这个是临时改容器内文件的做法但不建议长期依赖。容器的文件系统是临时的容器被删除后一切改动都会消失正确的做法是用数据卷volume挂载这部分在后面 MySQL 实例里具体讲。5. 每个新手都逃不过的两个部署实例MySQL 8.0 与 Redis 主从热搜词里docker安装mysql失败、docker安装mysql8.0并使用、docker安装redis主从占了很大比例说明数据库类应用是新手最普遍的实战场景。这两个实例跑通你基本就能理解 Docker 在数据持久化、端口映射、多容器协作上的核心用法。5.1 用 MySQL 8.0 理解端口映射和数据持久化先看一个新手最常见的失败案例。很多人在 Docker 里装 MySQL 失败错误信息是docker: Error response from daemon: driver failed programming external connectivity on endpoint查了半天发现是端口被占用。宿主机的 3306 已经被本地安装的 MySQL 占了Docker 再映射 3306 自然冲突。解决办法很简单把宿主机的映射端口换掉docker run -d \ --name mysql8 \ -p 3307:3306 \ -e MYSQL_ROOT_PASSWORDyourpassword \ -e MYSQL_DATABASEtestdb \ -v mysql_data:/var/lib/mysql \ mysql:8.0这里有几个关键点要讲透第一-e环境变量是 MySQL 镜像的配置入口。MYSQL_ROOT_PASSWORD设置 root 密码MYSQL_DATABASE在首次启动时自动创建数据库。如果忘了设置 root 密码容器启动后你是进不去的到时候又要查一堆初始化方法所以这一步最好在run时想清楚。第二-v mysql_data:/var/lib/mysql是数据卷挂载。mysql_data是命名卷Docker 会把容器里/var/lib/mysql目录的数据存到宿主机一个专门管理的目录下。这样即使容器被删除数据还在下次用同一个卷名启动新容器数据自动接上。这一点极其重要容器的文件系统是临时的不加数据卷rm 掉容器等于删除数据库。启动后连接测试docker exec -it mysql8 mysql -uroot -p输入密码进入 MySQL 命令行后你可以执行show databases;看到 testdb 已经创建。如果想从宿主机外部访问要确认宿主机的 3307 端口能被连接防火墙问题不在这里展开但记住 MySQL 8.0 的默认认证插件是 caching_sha2_password老客户端连不上会报Authentication plugin caching_sha2_password cannot be loaded需要客户端升级或用ALTER USER root% IDENTIFIED WITH mysql_native_password BY password;兼容。用docker inspect mysql8可以查看容器的 IP 和挂载信息排查网络和数据卷问题时这条命令很有用新手往往不知道容器有独立的 IP总以为容器和宿主机共享网络栈。5.2 Docker 里搭建 Redis 主从理解容器网络的入门Redis 主从搭建是热搜词里另一个高频需求。用 Docker 装两个 Redis 容器让一个当主节点、一个当从节点套路和物理机差不多但关键区别在于容器之间的网络通信。先创建 Docker 网络这一步经常被忽略docker network create redis-net为什么要手动创建网络因为默认的 bridge 网络里容器可以通过 IP 互访但 IP 是动态的重启可能就变了。自定义网络的好处是提供了内置 DNS 解析容器之间可以用容器名互相访问比如从库配置里写replicaof redis-master 6379就可以了IP 变了也不影响。这是在 Docker 里玩多容器协作时最重要的基建认知。启动主节点docker run -d --name redis-master --network redis-net -p 6379:6379 redis:7 redis-server --appendonly yes启动从节点docker run -d --name redis-slave --network redis-net -p 6380:6379 redis:7 redis-server --replicaof redis-master 6379注意最后一段是覆盖容器默认启动命令的写法。redis:7是镜像后面redis-server --replicaof redis-master 6379是自定义启动参数意思是让这个 Redis 实例作为 6379 端口主节点的从库。通过docker exec -it redis-slave redis-cli info replication可以看到role:slave和master_link_status:up。这一步跑通说明你已经理解了 Docker 多容器通信的基本方式后面部署微服务、一般的前后端分离项目都用这个套路。5.3 Docker Compose把多容器配置固化下来手动docker run两个 Redis 容器已经能跑了但如果这个服务要复制到别的机器或者团队里别人也要搭一套手敲命令显然不优雅。Docker Compose 的价值就是用 YAML 文件把多容器编排固化下来。先写一个docker-compose.yml文件version: 3.8 services: redis-master: image: redis:7 container_name: redis-master command: redis-server --appendonly yes ports: - 6379:6379 networks: - redis-net redis-slave: image: redis:7 container_name: redis-slave command: redis-server --replicaof redis-master 6379 ports: - 6380:6379 depends_on: - redis-master networks: - redis-net networks: redis-net: driver: bridge然后执行docker compose up -dCompose 会按照文件定义自动创建网络、拉镜像、启动容器。注意depends_on只是控制启动顺序并不保证主节点已经完全就绪所以在一些需要依赖就绪的场景下还要配合健康检查healthcheck使用。这是从能用走向好用的关键一步。MySQL 也可以加进 Compose顺便把前面的数据卷、端口映射、环境变量都写在文件里。以后部署一整套环境只需docker compose up -d一条命令这就是 Docker 对开发运维体验改变最大的地方。6. 日常使用高频故障排查手册实测记录这部分全部来自实际使用中踩过的坑按出现频率排序每一条都给出判断思路和解决方法。6.1 权限错误permission denied while trying to connect to the Docker daemon socket这是提问率最高的报错之一出现在 Linux 上执行 docker 命令时。完整报错通常是permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock意思是当前用户没有访问 Docker 守护进程 socket 的权限。解决方案前面提过把用户加进 docker 组sudo usermod -aG docker $USER执行后必须注销当前会话或者重启系统组权限才会生效。有时候groups命令已经显示你在 docker 组里了但当前 shell 的权限缓存还没更新需要重启 shell 或重新登录。另外有一种变体是docker: permission denied伴随/var/run/docker.sock挂载卷的情况通常是容器里要访问宿主机的 Docker socket但 socket 文件权限是 660 且属主是 root:docker容器内用户无权限时的处理方式是要么用 root 用户运行容器要么把 socket 文件的组权限放开——不过后者有安全风险一般不推荐。6.2 镜像下载慢的根治思路docker镜像下载慢几乎是所有国内用户必经的坎。核心思路是换镜像加速源。Docker Engine 和 Docker Desktop 都要改daemon.jsonLinux 路径是/etc/docker/daemon.jsonDocker Desktop 在 Settings - Docker Engine 里编辑 JSON。一个可行的配置示例{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com, https://docker.mirrors.ustc.edu.cn ] }改完重启 Docker。不同加速源的稳定性波动很大如果一个镜像源拉不动换另一个。注意国内镜像加速源并不能加速所有仓库比如某些小众仓库可能不在加速列表里这时可以用代理或换源方案。另外拉取不存在的镜像名时也会表现为下载慢或者一直转圈用docker pull前先到 Docker Hub 上确认镜像名拼写正确。6.3 容器网络不通的定位方法docker网络不通涵盖的情况很多但新手最常见的是三种宿主机访问容器端口不通、容器访问外网不通、容器之间互相不通。宿主机访问容器端口不通时先用docker ps确认真实端口映射。有时候你自己敲了-p 8080:80但容器里面 Nginx 监听的是 8000这时候访问当然不通。用docker port my-nginx查看当前映射关系一目了然。容器访问外网不通时先在容器里执行docker exec -it my-nginx ping 8.8.8.8如果 ping 不通但宿主机能上网多半是 Docker 默认 bridge 网络的 iptables 规则被清了或者开了防火墙。检查/etc/docker/daemon.json里的iptables: false是否被误设以及sysctl net.ipv4.ip_forward是否为 1。有些云服务器厂商的镜像默认把 ip_forward 关了导致容器无法上网这个坑比较隐蔽。容器之间互相不通时检查它们是否在同一个网络里。前面强调过自定义网络有 DNS 解析如果两个容器一个在默认 bridge 网、一个在自定义网络用容器名是 ping 不通的。解决时把它们放到同一网络docker network connect redis-net my-nginx6.4 服务启动失败failed to start docker application container engine这条报错在前面 Docker Desktop 小节提过但在纯 Docker Engine 环境下也常见。排查顺序是sudo systemctl status docker sudo journalctl -u docker --no-pager | tail -50日志里如果出现failed to start daemon: error while opening volume store metadata多半是/var/lib/docker目录权限损坏修复方式是sudo chown -R root:root /var/lib/docker sudo chmod -R 755 /var/lib/docker但注意这只在确认数据不重要时才建议操作。如果日志里出现overlay2 is not supported说明当前文件系统不支持 OverlayFS 存储驱动可以改用 vfs 或 fuse-overlayfs但性能会受影响。反复遇到服务启动失败的话建议把daemon.json暂时移走用默认配置启动确认是不是自己的配置导致的问题。这一步成本很低能排除掉大部分配置型故障。6.5 容器退出状态的快速判断docker ps -a看到 Exited(0) 和 Exited(1) 的意义完全不同。Exited(0) 是正常退出比如docker run --rm hello-world打印完内容就退出这是正常现象。Exited(1) 或非零状态码说明程序运行时出错。快速查看退出时的日志用docker logs 容器名查看即可。有一种常见情况是前台进程跑完就退出比如启动一个容器但命令是bash没有任何交互进程容器立刻退出。这时候加上-it交互终端就能保持运行或者用-d跑一个自带常驻进程的镜像如nginx。个人实际经验里Docker 排查问题的大原则是先看日志、再看网络、最后才考虑重启和重装。很多新手一遇到问题就docker rm -f再来一遍这样不仅学不到东西还可能把数据卷里的数据一并删掉。先理解报错信息在说什么再动手这个习惯能帮你省非常多的无用功。最后再补充一个实用的小技巧如果你经常在一台机器上同时跑多个项目尽量不要让所有容器都在默认 bridge 网络上按照项目维度创建各自的网络配合 Compose 文件管理这样端口不冲突、容器名不冲突、网络也清晰。等你真正熟悉了这套操作就会理解为什么很多人说Docker 用好了部署一个服务真的只需要一条命令。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表