前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
简介
在许多情况下,您可能需要将数据和操作需求从一个服务器迁移到另一个服务器。您可能需要在新的数据中心实施解决方案,升级到更大的机器,或者过渡到新的硬件或新的 VPS 提供商。
无论您的原因是什么,在从一个系统迁移到另一个系统时,您应该考虑许多不同的因素。如果您没有使用 Chef、Puppet 或 Ansible 等配置管理解决方案,要获得功能上等效的配置可能会很困难。您不仅需要传输数据,还需要配置您的服务在新机器上以相同的方式运行。
在本指南中,您将了解如何准备源系统和目标系统进行迁移。这将包括让您的两台机器使用 SSH 密钥进行通信,并调查需要转移的组件。您将在本系列的下一篇文章中开始实际迁移。
步骤 1 – 创建备份
执行任何可能具有破坏性的操作时,首先要采取的步骤是创建全新的备份。您不希望在替换正在运行的生产机器之前,某个命令在当前生产机器上出现故障。
有许多不同的方法可以备份服务器。您的选择将取决于对您的情况有意义的选项以及您最熟悉的选项。
如果您可以访问物理硬件并有备份空间(磁盘驱动器、USB 等),您可以使用许多可用的镜像备份解决方案之一来克隆磁盘。在处理云服务器时,功能上等效的方法是在控制面板界面内拍摄快照或镜像。
完成备份后,您就可以继续进行下一步了。在本指南的其余部分,您将需要以 root 用户身份运行许多命令,或者使用 sudo
。
步骤 2 – 收集有关源系统的信息
在开始迁移之前,您应该配置目标系统以匹配源系统。
您将希望在当前服务器和计划迁移到的服务器之间尽可能匹配。您可能希望在迁移到较新的目标系统之前升级当前服务器,并在此之后再次进行备份。重要的是,当开始实际迁移时,它们尽可能匹配。
大部分可以帮助您决定为新机器创建哪种服务器系统的信息可以使用 uname
命令检索:
uname -r
5.4.0-26-generic
这是您当前系统正在运行的内核版本。为了使事情顺利进行,最好尝试在目标系统上匹配它。
您还应该尝试匹配源服务器的发行版和版本。如果您不知道在源机器上安装的发行版版本,可以通过输入以下命令来查找:
cat /etc/issue
Ubuntu 20.04.3 LTS \n \l
如果可能的话,您应该使用相同的参数创建新服务器。在这种情况下,您将创建一个 Ubuntu 20.04 系统。您还应尽量匹配内核版本。通常情况下,这应该是来自您的 Linux 发行版存储库的最新内核。
步骤 3 – 在源和目标服务器之间设置 SSH 密钥访问
您需要让您的服务器能够通信以便传输文件。为了做到这一点,您应该在它们之间交换 SSH 密钥。您可以学习如何在 Linux 服务器上配置 SSH 密钥。
您需要在目标服务器上创建一个新密钥,以便将其添加到现有服务器的 authorized_keys
文件中。这比另一种方式更清晰,因为这样,当迁移完成时,新服务器的 authorized_keys
文件中就不会有多余的密钥。
首先,在目标机器上,通过输入以下命令检查您的 root 用户是否已经拥有 SSH 密钥:
ls ~/.ssh
authorized_keys
如果您看到名为 id_rsa.pub
和 id_rsa
的文件,则表示您已经拥有密钥,您只需要将它们传输过去。
如果您没有看到这些文件,可以使用 ssh-keygen
创建新的密钥对:
ssh-keygen -t rsa
按照提示按下 “Enter” 键以接受默认值。
现在,您可以通过 ssh
将密钥传输到源服务器:
cat ~/.ssh/id_rsa.pub | ssh other_server_ip "cat >> ~/.ssh/authorized_keys"
现在,您应该能够在目标系统上自由地通过 SSH 连接到源服务器,而无需提供密码:
ssh other_server_ip
这将使任何进一步的迁移步骤更加顺利。
步骤 4 – 创建需求清单
现在你将进行系统的深入分析。
在运营过程中,你的软件需求可能会发生变化。有时旧服务器上可能存在一些曾经需要的服务和软件,但已经被替换。
一般来说,不需要的服务可以被禁用,如果完全不需要,也可以被卸载,但是清点它们可能会耗费时间。你需要发现在源服务器上正在使用的服务,然后决定这些服务是否应该存在于新服务器上。
你发现服务和运行级别的方式取决于服务器所采用的“init”系统的类型。init 系统负责在用户命令或自动启动和停止服务。从 2014 年开始,几乎所有主要的 Linux 发行版都采用了一个名为 Systemd 的 init 系统,本指南将反映 Systemd。
为了列出已注册到 Systemd 的服务,你可以使用 systemctl
命令:
systemctl list-units -t service
UNIT LOAD ACTIVE SUB DESCRIPTION >
accounts-daemon.service loaded active running Accounts Service >
apparmor.service loaded active exited Load AppArmor profiles >
apport.service loaded active exited LSB: automatic crash repor>
atd.service loaded active running Deferred execution schedul>
blk-availability.service loaded active exited Availability of block devi>
cloud-config.service loaded active exited Apply the settings specifi>
cloud-final.service loaded active exited Execute cloud user/final s>
cloud-init-local.service loaded active exited Initial cloud-init job (pr>
cloud-init.service loaded active exited Initial cloud-init job (me>
console-setup.service loaded active exited Set console font and keyma>
containerd.service loaded active running containerd container runti>
…
Systemd 通过“targets”实现服务管理。传统 init 系统的系统一次只能处于一个“运行级别”,而使用 Systemd 的服务器可以同时达到多个 targets。这在实践中更加灵活,但确定哪些服务是活动的可能更加困难。
你可以通过输入以下命令来查看当前活动的 targets:
systemctl list-units -t target
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
cloud-config.target loaded active active Cloud-config availability
cloud-init.target loaded active active Cloud-init target
cryptsetup.target loaded active active Local Encrypted Volumes
getty.target loaded active active Login Prompts
graphical.target loaded active active Graphical Interface
local-fs-pre.target loaded active active Local File Systems (Pre)
local-fs.target loaded active active Local File Systems
multi-user.target loaded active active Multi-User System
network-online.target loaded active active Network is Online
…
你可以通过输入以下命令来列出所有可用的 targets:
systemctl list-unit-files -t target
UNIT FILE STATE VENDOR PRESET
basic.target static enabled
blockdev@.target static enabled
bluetooth.target static enabled
boot-complete.target static enabled
cloud-config.target static enabled
cloud-init.target enabled-runtime enabled
cryptsetup-pre.target static disabled
cryptsetup.target static enabled
ctrl-alt-del.target disabled enabled
…
从这里,你可以找出每个 target 关联的服务。Targets 可以有服务或其他 targets 作为依赖项,因此你可以通过输入以下命令来查看每个 target 实施的策略:
systemctl list-dependencies target_name.target
multi-user.target
是 Systemd 服务器上常用的一个 target,在启动过程中达到该目标时,用户可以登录。例如,你可以输入以下命令:
systemctl list-dependencies multi-user.target
multi-user.target
● ├─apport.service
● ├─atd.service
● ├─console-setup.service
● ├─containerd.service
● ├─cron.service
● ├─dbus.service
● ├─dmesg.service
● ├─docker.service
● ├─grub-common.service
● ├─grub-initrd-fallback.service
…
这将列出该目标的依赖树,给出当达到该目标时启动的服务和其他 targets 的列表。
通过其他方法检查服务
虽然大多数由软件包管理器配置的服务将被注册到 init 系统中,但一些其他软件,如 Docker 部署,可能不会。
你可以尝试通过查看这些服务使用的网络端口和 Unix 套接字来找到这些其他服务和进程。在大多数情况下,服务以某种方式相互通信或与外部实体通信。服务器上只有一定数量的接口可以用于服务通信,检查这些接口是发现其他服务的好方法。
你可以使用 netstat
工具来发现正在使用的网络端口和 Unix 套接字。你可以使用 -nlp
标志运行 netstat
以获得概述:
netstat -nlp
-n
指定输出中应显示数字 IP 地址,而不是主机名或用户名。在检查本地服务器时,这通常更加信息丰富。-l
指定netstat
只显示活动监听套接字。-p
显示每个使用端口或套接字的进程 ID(PID)和名称。
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:8200 0.0.0.0:* LISTEN 104207/vault
tcp 0 0 0.0.0.0:1935 0.0.0.0:* LISTEN 3691671/nginx: mast
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 3691671/nginx: mast
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3691671/nginx: mast
tcp 0 0 0.0.0.0:1936 0.0.0.0:* LISTEN 197885/stunnel4
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 162540/systemd-reso
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 129518/sshd: /usr/s
tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN 99465/node /root/he
tcp 0 0 0.0.0.0:8088 0.0.0.0:* LISTEN 3691671/nginx: mast
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 3691671/nginx: mast
tcp 0 0 0.0.0.0:56733 0.0.0.0:* LISTEN 170269/docker-proxy
tcp6 0 0 :::80 :::* LISTEN 3691671/nginx: mast
tcp6 0 0 :::22 :::* LISTEN 129518/sshd: /usr/s
tcp6 0 0 :::443 :::* LISTEN 3691671/nginx: mast
tcp6 0 0 :::56733 :::* LISTEN 170275/docker-proxy
udp 0 0 127.0.0.53:53 0.0.0.0:* 162540/systemd-reso
raw6 0 0 :::58 :::* 7 162524/systemd-netw
raw6 0 0 :::58 :::* 7 162524/systemd-netw
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node PID/Program name Path
unix 2 [ ACC ] STREAM LISTENING 5313074 1/systemd /run/systemd/userdb/io.systemd.DynamicUser
unix 2 [ ACC ] SEQPACKET LISTENING 12985 1/systemd /run/udev/control
unix 2 [ ACC ] STREAM LISTENING 12967 1/systemd /run/lvm/lvmpolld.socket
unix 2 [ ACC ] STREAM LISTENING 12980 1/systemd /run/systemd/journal/stdout
unix 2 [ ACC ] STREAM LISTENING 16037236 95187/systemd /run/user/0/systemd/private
…
netstat
输出包含两个独立的块 —— 一个用于网络端口,一个用于套接字。如果你在这里看到了通过 init 系统没有信息的服务,你将不得不弄清楚原因,并确定是否打算迁移这些服务。
你可以使用 lsof
命令获取关于服务提供的端口的类似信息:
lsof
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node\x20/ 99465 root 20u IPv4 16046039 0t0 TCP 127.0.0.1:3000 (LISTEN)
vault 104207 vault 8u IPv4 1134285 0t0 TCP *:8200 (LISTEN)
sshd 129518 root 3u IPv4 1397496 0t0 TCP *:22 (LISTEN)
sshd 129518 root 4u IPv6 1397507 0t0 TCP *:22 (LISTEN)
systemd-r 162540 systemd-resolve 12u IPv4 5313507 0t0 UDP 127.0.0.53:53
systemd-r 162540 systemd-resolve 13u IPv4 5313508 0t0 TCP 127.0.0.53:53 (LISTEN)
docker-pr 170269 root 4u IPv4 1700561 0t0 TCP *:56733 (LISTEN)
docker-pr 170275 root 4u IPv6 1700573 0t0 TCP *:56733 (LISTEN)
stunnel4 197885 stunnel4 9u IPv4 1917328 0t0 TCP *:1936 (LISTEN)
sshd 3469804 root 4u IPv4 22246413 0t0 TCP 159.203.102.125:22->154.5.29.188:36756 (ESTABLISHED)
nginx 3691671 root 7u IPv4 2579911 0t0 TCP *:8080 (LISTEN)
nginx 3691671 root 8u IPv4 1921506 0t0 TCP *:80 (LISTEN)
nginx 3691671 root 9u IPv6 1921507 0t0 TCP *:80 (LISTEN)
nginx 3691671 root 10u IPv6 1921508 0t0 TCP *:443 (LISTEN)
nginx 3691671 root 11u IPv4 1921509 0t0 TCP *:443 (LISTEN)
nginx 3691671 root 12u IPv4 2579912 0t0 TCP *:8088 (LISTEN)
nginx 3691671 root 13u IPv4 2579913 0t0 TCP *:1935 (LISTEN)
nginx 3691674 www-data 7u IPv4 2579911 0t0 TCP *:8080 (LISTEN)
nginx 3691674 www-data 8u IPv4 1921506 0t0 TCP *:80 (LISTEN)
nginx 3691674 www-data 9u IPv6 1921507 0t0 TCP *:80 (LISTEN)
nginx 3691674 www-data 10u IPv6 1921508 0t0 TCP *:443 (LISTEN)
nginx 3691674 www-data 11u IPv4 1921509 0t0 TCP *:443 (LISTEN)
nginx 3691674 www-data 12u IPv4 2579912 0t0 TCP *:8088 (LISTEN)
nginx 3691674 www-data 13u IPv4 2579913 0t0 TCP *:1935 (LISTEN)
netstat
和 lsof
都是核心 Linux 进程管理工具,在各种其他情境中都很有用。
第五步 – 收集软件包版本
此时,你应该已经对源服务器上运行的服务有了一个很好的了解,你应该在目标服务器上实施这些服务。
你应该有一个服务列表,你知道你需要在新服务器上实施这些服务。为了顺利过渡,重要的是尽可能匹配版本。
你不一定要审查源系统上安装的每个软件包,并尝试在新系统上复制它,但你应该检查对你的需求重要的软件组件,并尝试找到它们的版本号。
你可以尝试从软件本身获取版本号,有时通过向每个命令传递 -v
或 --version
标志,但通过你的软件包管理器更加直接。如果你使用基于 Ubuntu/Debian 的系统,你可以使用 dpkg
命令查看安装的软件包版本:
dpkg -l | grep package_name
如果你使用基于 Rocky Linux、RHEL 或 Fedora 的系统,你可以使用 rpm
来实现相同的目的:
rpm -qa | grep package_name
这将让你对要匹配的软件包版本有一个很好的了解。确保保留任何相关软件的版本号。
结论
现在,你应该已经很清楚源服务器上需要迁移到新机器的进程和服务。你还应该已经完成了允许你的两台服务器相互通信的初步步骤。
你的迁移基础现在已经完成。在本系列的下一篇文章中,你将开始实际的迁移过程。