云服务器中使用 Docker 搭建子服务器
在云计算环境中,使用 Docker 容器技术可以实现更灵活的服务部署方案。本文介绍如何利用Docker 搭建轻量级的子服务器,减少对特定云服务提供商的依赖,实现快速迁移。
你有没有遇到过这种情况:在一台云服务器上辛辛苦苦配好了环境、装好了各种依赖,结果某天需要换服务商或者加一台机器,发现所有事情得从头来一遍?
这正是我开始用 Docker 搭建”子服务器”的原因。把应用跑在容器里,而不是直接装在宿主机上,迁移的时候打个包就走,几分钟就能在新机器上跑起来。
为什么选择 Docker?
直接在云服务器上部署应用当然可以,但时间一长你会发现几个头疼的问题:环境难以复现、迁移成本高、不同应用之间互相干扰。Docker 恰好解决了这些痛点。
先来看一下两种部署方式的对比:
| 对比维度 | 直接部署 | Docker 部署 |
|---|---|---|
| 环境一致性 | 每台机器手动配置,容易出现”我这能跑” | 镜像打包,到哪都一样 |
| 迁移成本 | 重新安装所有依赖,耗时数小时 | 导出镜像 + 导入,几分钟搞定 |
| 应用隔离 | 共享系统环境,依赖可能冲突 | 容器独立运行,互不干扰 |
| 资源占用 | 直接使用系统资源,无额外开销 | 轻微的容器开销,远低于虚拟机 |
| 启动速度 | 取决于应用本身 | 秒级启动 |
| 回滚能力 | 无,除非提前备份整个系统 | 保留旧镜像即可随时回滚 |
简单来说,Docker 让你的服务器环境变成了”随身携带”的东西,而不是绑死在某台机器上。
Docker 基础操作指南
接下来我们从零开始,一步一步把容器跑起来。
配置 Docker 权限
装好 Docker 之后,第一件事是把当前用户加到 docker 用户组里。不然每次执行命令都要加 sudo,用起来很烦:
sudo usermod -aG docker $USER
[!WARNING] 添加用户组后必须重新登录才能生效。直接跑
docker ps会报permission denied错误,不要以为命令没执行成功。
Docker 容器管理
创建并运行容器
一行命令就能创建一个基于 Ubuntu 的容器,同时把 SSH 端口映射出来:
docker run --name my_server -p 20000:22 -itd ubuntu:20.04
参数说明:
| 参数 | 作用 |
|---|---|
--name my_server | 指定容器名称,方便后续管理 |
-p 20000:22 | 将容器的 22 端口映射到宿主机的 20000 端口 |
-itd | 交互式终端 + 后台运行 |
ubuntu:20.04 | 使用的基础镜像 |
端口映射这一步很关键——之后你就可以通过宿主机的 20000 端口 SSH 进容器了,就像连接一台独立的服务器一样。
进入容器
容器跑起来之后,用 attach 进去:
docker attach my_server
进去第一件事,给 root 设个密码,不然后面配 SSH 的时候会很麻烦:
passwd
容器操作技巧
有个小技巧很实用:想要临时退出容器但又不想把它停掉,可以用挂起操作:
- 先按 Ctrl+p
- 再按 Ctrl+q
[!IMPORTANT] 这两个按键要快速连续按。如果直接输
exit或按 Ctrl+d,容器会被停止。这个区别在生产环境中尤为关键——误停容器可能导致服务中断。
容器迁移方案
这是整篇文章最核心的部分——怎么把一个配好的容器搬到另一台机器上。整个流程分五步,看起来多,但每一步都很简单。
graph LR
A[运行中的容器] -->|docker commit| B[本地镜像]
B -->|docker save| C[.tar 文件]
C -->|scp 传输| D[目标服务器]
D -->|docker load| E[目标镜像]
E -->|docker run| F[新容器]
容器迁移步骤清单
- 用
docker commit将运行中的容器保存为镜像 - 用
docker save将镜像导出为.tar文件 - 设置文件权限,用 SCP 或
rsync传输到目标服务器 - 在目标服务器上用
docker load加载镜像 - 用
docker run从镜像创建新容器并验证服务正常
1.将容器保存为镜像
docker commit my_server my_custom_image:v1
2.将镜像导出为文件
docker save -o my_server_image.tar my_custom_image:v1
3.设置文件权限并传输
chmod +r my_server_image.tar
scp my_server_image.tar user@new-server:/path/to/destination
[!TIP] 镜像文件可能很大(几百 MB 到几 GB)。如果服务器带宽有限,可以先
gzip压缩再传输:gzip my_server_image.tar,到目标机器后gunzip解压即可。
4.在新服务器上加载镜像
docker load -i my_server_image.tar
5.从镜像创建新容器
docker run --name my_server -p 20000:22 -itd my_custom_image:v1
走完这五步,你在旧服务器上的所有配置、安装的软件、修改的文件,全部都原封不动地搬到了新服务器上。这就是 Docker 最让人省心的地方。
容器配置技巧
容器跑起来之后,还有几个实用的配置值得做。
加速软件安装
如果你的服务器在国内,apt 默认的源下载速度会很慢。换成清华大学开源软件镜像站可以大幅提升速度。
这一步建议在容器创建后第一时间做,后面装什么都会快很多。
用户管理
生产环境下不建议一直用 root 操作,创建一个普通用户并给 sudo 权限是更安全的做法:
adduser username
usermod -aG sudo username
自定义登录欢迎信息
如果你管理多个容器,自定义一下登录时的欢迎信息可以帮你快速区分当前在哪个环境里:
nano /etc/update-motd.d
Dockerfile 最佳实践
如果你经常需要创建类似的容器,手动配置就太低效了。写一个 Dockerfile 把初始化步骤固化下来,后续一行 docker build 就能产出一个开箱即用的镜像。
Dockerfile 示例
FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN sed -i 's|http://archive.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
openssh-server sudo vim curl \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir /run/sshd
RUN useradd -m -s /bin/bash admin \
&& echo "admin:changeme" | chpasswd \
&& usermod -aG sudo admin
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
几个关键点:
- 合并 RUN 指令:每个
RUN都会产生一层镜像,合并能显著减小镜像体积 - 清理缓存:
rm -rf /var/lib/apt/lists/*清理 apt 缓存,进一步缩小镜像 - 使用
--no-install-recommends:只装必要的包,不装推荐包
更多 Dockerfile 编写技巧可参考 Docker 官方最佳实践文档。
常见问题排查
[!NOTE] 以下是我踩过的一些坑,提前了解能省不少时间。
容器启动后立即退出
通常是因为容器没有前台进程。确保用了 -itd 参数,或者容器内有一个持续运行的服务(如 sshd)。用 docker logs my_server 查看退出原因。
SSH 连不上容器
检查这几项:容器内是否安装了 openssh-server、sshd 服务是否启动、端口映射是否正确、防火墙是否放行了映射端口。
docker load 报错 “no space left on device”
Docker 默认的存储目录在 /var/lib/docker,磁盘空间不够就会报这个错。用 docker system prune 清理无用的镜像和容器,或者通过 daemon.json 修改存储路径。
scp 传输速度很慢
除了前面提到的 gzip 压缩外,还可以用 rsync --progress 替代 scp,支持断点续传,传大文件更稳。
写在最后
用 Docker 搭建子服务器这个方案,我自己用下来最大的感受就是”安心”。不用再担心换服务商的时候要重新配环境,也不用担心某个应用的依赖把系统搞乱。每个容器都是独立的,打包带走就行。
如果你也经常需要在多台服务器之间折腾,或者想给自己的部署流程留一条后路,不妨试试这个思路。