返回

云服务器中使用 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

容器操作技巧

有个小技巧很实用:想要临时退出容器但又不想把它停掉,可以用挂起操作:

  1. 先按 Ctrl+p
  2. 再按 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 文件
  • 设置文件权限,用 SCPrsync 传输到目标服务器
  • 在目标服务器上用 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 搭建子服务器这个方案,我自己用下来最大的感受就是”安心”。不用再担心换服务商的时候要重新配环境,也不用担心某个应用的依赖把系统搞乱。每个容器都是独立的,打包带走就行。

如果你也经常需要在多台服务器之间折腾,或者想给自己的部署流程留一条后路,不妨试试这个思路。