如何迁移 Linux 服务器 第 1 部分 - 系统准备

介绍

有许多情况下,您可能需要将数据和操作需求从一个服务器迁移到另一个服务器,您可能需要在新的数据中心实现解决方案,升级到更大的机器,或过渡到新的硬件或新的VPS提供商。

无论你的原因是什么,在从一个系统迁移到另一个系统时,你应该考虑很多不同的因素。如果你不使用 Chef、Puppet 或 Ansible 等配置管理解决方案,就很难获得功能相同的配置。

<$>[注] 注: 作为一般注意,现代部署应该随时使用配置管理系统,无论是设计为暂时的Kubernetes节点,还是运行系统服务和集装箱软件的组合。

在本指南中,您将审查如何为迁移准备您的源和目标系统. 这将包括让您的两台机器与SSH密钥进行通信,并调查哪些组件需要转移。

步骤一:备份

执行任何潜在破坏性的操作时要采取的第一个步骤是创建新的备份. 您不希望被留在一个命令在更换开始运行之前破坏当前生产机器上的东西的情况下。

有许多不同的方法来备份您的服务器. 您的选择将取决于哪些选项对您的场景有意义,以及您最舒适的选择。

如果您可以访问物理硬件和备份空间(磁盘驱动器,USB等),您可以使用许多可用的图像备份解决方案来克隆磁盘。

一旦您完成了备份,您将准备好继续运行,对于本指南的剩余部分,您将需要运行许多命令作为 root,或使用sudo

步骤2:收集有关源系统的信息

在开始迁移之前,您应该将目标系统配置为匹配源系统。

您可能希望在迁移到更新的目标系统之前升级当前服务器,并在之后进行另一组备份。

帮助您决定为新机器创建哪个服务器系统的大部分信息可以用uname命令获取:

1uname -r
1[secondary_label Output]
25.4.0-26-generic

这是你当前系统正在运行的内核的版本. 为了让事情顺利进行,尝试在目标系统上匹配它是一个好主意。

您还应该尝试匹配源服务器的发行版和版本. 如果您不知道您在源机上安装的发行版的版本,您可以通过键入来查找:

1cat /etc/issue
1[secondary_label Output]
2Ubuntu 20.04.3 LTS \n \l

如果可能的话,你应该创建新的服务器,具有相同的参数。在这种情况下,你会创建一个Ubuntu 20.04系统。你也应该尽可能地尝试匹配内核版本。

步骤 3 – 设置源和目标服务器之间的 SSH 密钥访问

你需要你的服务器能够通信,以便他们可以传输文件. 为了做到这一点,你应该在它们之间交换 SSH 密钥. 你可以学习 如何在 Linux 服务器上配置 SSH 密钥

您需要在目标服务器上创建一个新密钥,以便您可以将其添加到现有服务器的autorized_keys文件中。

首先,在您的目标机器上,检查您的 root 用户是否已经没有 SSH 密钥,键入:

1ls ~/.ssh
1[secondary_label Output]
2authorized_keys

如果你看到名为id_rsa.pubid_rsa的文件,那么你已经有密钥,你只需要转移它们。

如果您看不到这些文件,请使用ssh-keygen创建一个新的密钥对:

1ssh-keygen -t rsa

点击进入通过所有提示,以接受默认值。

现在,您可以通过ssh来传输密钥到源服务器:

1cat ~/.ssh/id_rsa.pub | ssh other_server_ip "cat >> ~/.ssh/authorized_keys"

您现在应该能够在没有提供密码的情况下从目标系统自由地 SSH 到源服务器:

1ssh other_server_ip

这将使任何进一步的迁移步骤更顺利。

步骤4:创建要求列表

现在你实际上会做一些对你的系统的深入分析。

在运行过程中,您的软件需求可能会发生变化,有时旧的服务器有某些服务和软件,在某个时候是需要的,但已经被更换。

一般来说,不必要的服务可以被禁用,如果完全不必要,则可以被卸载,但记录它们可能需要时间。

您发现服务和运行水平的方式取决于您的服务器使用的init系统的类型。 init 系统负责启动和停止服务,无论是在用户的命令下还是自动。

要列出在 Systemd 注册的服务,您可以使用systemctl命令:

1systemctl list-units -t service
 1[secondary_label Output]
 2  UNIT LOAD ACTIVE SUB DESCRIPTION               >
 3  accounts-daemon.service loaded active running Accounts Service          >
 4  apparmor.service loaded active exited Load AppArmor profiles    >
 5  apport.service loaded active exited LSB: automatic crash repor>
 6  atd.service loaded active running Deferred execution schedul>
 7  blk-availability.service loaded active exited Availability of block devi>
 8  cloud-config.service loaded active exited Apply the settings specifi>
 9  cloud-final.service loaded active exited Execute cloud user/final s>
10  cloud-init-local.service loaded active exited Initial cloud-init job (pr>
11  cloud-init.service loaded active exited Initial cloud-init job (me>
12  console-setup.service loaded active exited Set console font and keyma>
13  containerd.service loaded active running containerd container runti>
14

对于服务管理,Systemd 实施了目标的概念,而传统 init 系统的系统可能同时只处于一个运行级别,但使用Systemd 的服务器可以同时达到多个目标。

您可以通过键入查看当前活跃的目标:

1systemctl list-units -t target
 1[secondary_label Output]
 2  UNIT LOAD ACTIVE SUB DESCRIPTION
 3  basic.target loaded active active Basic System
 4  cloud-config.target loaded active active Cloud-config availability
 5  cloud-init.target loaded active active Cloud-init target
 6  cryptsetup.target loaded active active Local Encrypted Volumes
 7  getty.target loaded active active Login Prompts
 8  graphical.target loaded active active Graphical Interface
 9  local-fs-pre.target loaded active active Local File Systems (Pre)
10  local-fs.target loaded active active Local File Systems
11  multi-user.target loaded active active Multi-User System
12  network-online.target loaded active active Network is Online
13

您可以通过键入列出所有可用的目标:

1systemctl list-unit-files -t target
 1[secondary_label Output]
 2UNIT FILE STATE VENDOR PRESET
 3basic.target static enabled
 4[email protected] static enabled
 5bluetooth.target static enabled
 6boot-complete.target static enabled
 7cloud-config.target static enabled
 8cloud-init.target enabled-runtime enabled
 9cryptsetup-pre.target static disabled
10cryptsetup.target static enabled
11ctrl-alt-del.target disabled enabled
12

目标可以有服务或其他目标作为依赖,因此您可以通过键入查看每个目标实施的策略:

1systemctl list-dependencies target_name.target

「multi-user.target」是 Systemd 服务器上常用的目标,在用户能够登录的启动流程中达到此点。

1systemctl list-dependencies multi-user.target
 1[secondary_label Output]
 2multi-user.target
 3● ├─apport.service
 4● ├─atd.service
 5● ├─console-setup.service
 6● ├─containerd.service
 7● ├─cron.service
 8● ├─dbus.service
 9● ├─dmesg.service
10● ├─docker.service
11● ├─grub-common.service
12● ├─grub-initrd-fallback.service
13

这将列出该目标的依赖树,为您列出当实现该目标时启动的服务和其他目标。

通过其他方法检查服务

虽然您的包管理器配置的大多数服务将与 init 系统注册,但某些其他软件,如 Docker 部署,可能不会注册。

您可以通过查看这些服务使用的网络端口和Unix接口来寻找这些其他服务和流程。在大多数情况下,服务以某种方式相互通信或与外部实体通信。

您可以使用的一个工具来发现网络端口和使用的Unix接口是netstat。您可以运行netstat-nlp旗帜,以获得概述:

1netstat -nlp
  • -n 指明在输出中应该显示数字 IP 地址,而不是主机名或用户名。 当检查本地服务器时,这通常更具信息性。
  • -l 指明 netstat 只能显示主动收听的接口。
  • -p 显示使用端口或接口的每个过程的 ID(`PID')和名称。
 1[secondary_label Output]
 2Active Internet connections (only servers)
 3Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
 4tcp 0 0 0.0.0.0:8200 0.0.0.0:*               LISTEN 104207/vault
 5tcp 0 0 0.0.0.0:1935 0.0.0.0:*               LISTEN 3691671/nginx: mast
 6tcp 0 0 0.0.0.0:8080 0.0.0.0:*               LISTEN 3691671/nginx: mast
 7tcp 0 0 0.0.0.0:80 0.0.0.0:*               LISTEN 3691671/nginx: mast
 8tcp 0 0 0.0.0.0:1936 0.0.0.0:*               LISTEN 197885/stunnel4
 9tcp 0 0 127.0.0.53:53 0.0.0.0:*               LISTEN 162540/systemd-reso
10tcp 0 0 0.0.0.0:22 0.0.0.0:*               LISTEN 129518/sshd: /usr/s
11tcp 0 0 127.0.0.1:3000 0.0.0.0:*               LISTEN 99465/node /root/he
12tcp 0 0 0.0.0.0:8088 0.0.0.0:*               LISTEN 3691671/nginx: mast
13tcp 0 0 0.0.0.0:443 0.0.0.0:*               LISTEN 3691671/nginx: mast
14tcp 0 0 0.0.0.0:56733 0.0.0.0:*               LISTEN 170269/docker-proxy
15tcp6 0 0 :::80                   :::*                    LISTEN 3691671/nginx: mast
16tcp6 0 0 :::22                   :::*                    LISTEN 129518/sshd: /usr/s
17tcp6 0 0 :::443                  :::*                    LISTEN 3691671/nginx: mast
18tcp6 0 0 :::56733                :::*                    LISTEN 170275/docker-proxy
19udp 0 0 127.0.0.53:53 0.0.0.0:*                           162540/systemd-reso
20raw6 0 0 :::58                   :::*                    7 162524/systemd-netw
21raw6 0 0 :::58                   :::*                    7 162524/systemd-netw
22Active UNIX domain sockets (only servers)
23Proto RefCnt Flags Type State I-Node PID/Program name Path
24unix 2      [ ACC ]     STREAM LISTENING 5313074 1/systemd            /run/systemd/userdb/io.systemd.DynamicUser
25unix 2      [ ACC ]     SEQPACKET LISTENING 12985 1/systemd            /run/udev/control
26unix 2      [ ACC ]     STREAM LISTENING 12967 1/systemd            /run/lvm/lvmpolld.socket
27unix 2      [ ACC ]     STREAM LISTENING 12980 1/systemd            /run/systemd/journal/stdout
28unix 2      [ ACC ]     STREAM LISTENING 16037236 95187/systemd        /run/user/0/systemd/private
29

netstat输出包含两个单独的块 - 一个用于网络端口,一个用于接口. 如果您在这里看到通过 init 系统没有信息的服务,您将不得不弄清楚为什么是这样,以及您是否打算迁移这些服务。

您可以通过使用lsof命令获得有关服务提供的端口的类似信息:

1lsof
 1[secondary_label Output]
 2COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
 3node\x20/   99465 root 20u IPv4 16046039 0t0 TCP 127.0.0.1:3000 (LISTEN)
 4vault 104207 vault 8u IPv4 1134285 0t0 TCP *:8200 (LISTEN)
 5sshd 129518 root 3u IPv4 1397496 0t0 TCP *:22 (LISTEN)
 6sshd 129518 root 4u IPv6 1397507 0t0 TCP *:22 (LISTEN)
 7systemd-r 162540 systemd-resolve 12u IPv4 5313507 0t0 UDP 127.0.0.53:53
 8systemd-r 162540 systemd-resolve 13u IPv4 5313508 0t0 TCP 127.0.0.53:53 (LISTEN)
 9docker-pr 170269 root 4u IPv4 1700561 0t0 TCP *:56733 (LISTEN)
10docker-pr 170275 root 4u IPv6 1700573 0t0 TCP *:56733 (LISTEN)
11stunnel4 197885 stunnel4 9u IPv4 1917328 0t0 TCP *:1936 (LISTEN)
12sshd 3469804 root 4u IPv4 22246413 0t0 TCP 159.203.102.125:22->154.5.29.188:36756 (ESTABLISHED)
13nginx 3691671 root 7u IPv4 2579911 0t0 TCP *:8080 (LISTEN)
14nginx 3691671 root 8u IPv4 1921506 0t0 TCP *:80 (LISTEN)
15nginx 3691671 root 9u IPv6 1921507 0t0 TCP *:80 (LISTEN)
16nginx 3691671 root 10u IPv6 1921508 0t0 TCP *:443 (LISTEN)
17nginx 3691671 root 11u IPv4 1921509 0t0 TCP *:443 (LISTEN)
18nginx 3691671 root 12u IPv4 2579912 0t0 TCP *:8088 (LISTEN)
19nginx 3691671 root 13u IPv4 2579913 0t0 TCP *:1935 (LISTEN)
20nginx 3691674 www-data 7u IPv4 2579911 0t0 TCP *:8080 (LISTEN)
21nginx 3691674 www-data 8u IPv4 1921506 0t0 TCP *:80 (LISTEN)
22nginx 3691674 www-data 9u IPv6 1921507 0t0 TCP *:80 (LISTEN)
23nginx 3691674 www-data 10u IPv6 1921508 0t0 TCP *:443 (LISTEN)
24nginx 3691674 www-data 11u IPv4 1921509 0t0 TCP *:443 (LISTEN)
25nginx 3691674 www-data 12u IPv4 2579912 0t0 TCP *:8088 (LISTEN)
26nginx 3691674 www-data 13u IPv4 2579913 0t0 TCP *:1935 (LISTEN)

netstatlsof都是Linux核心流程管理工具,在各种其他环境中都很有用。

步骤 5 – 收集包版本

在此时,您应该对您应该在目标服务器上实施的源机上运行哪些服务有很好的想法。

要让过渡顺利进行,重要的是尽可能地尝试匹配版本。

您不必尝试检查在源系统上安装的每个包,并尝试在新系统上复制它,但您应该检查对您的需求至关重要的软件组件,并尝试找到其版本号。

您可以尝试从软件本身获取版本号码,有时通过将-v--version旗帜传递给每个命令,但通过您的包管理器更容易做到这一点。

1dpkg -l | grep package_name

如果您使用的是基于Rocky Linux、RHEL 或Fedora的系统,您可以使用rpm来实现相同的目的:

1rpm -qa | grep package_name

这将给你一个很好的想法,你想要匹配的软件版本. 确保保留任何相关软件的版本号码。

结论

您现在应该对源服务器上的哪些流程和服务需要转移到新机器有一个很好的想法,您还应该完成初步步骤,以便您的两个服务器彼此通信。

本系列的下一篇文章,您将开始实际的迁移过程。

Published At
Categories with 技术
Tagged with
comments powered by Disqus