Tất cả hệ thống hoạt động bình thường Amsterdam · Paris · Reykjavík +5 Thanh toán bằng Tiền mã hoá
Mạng & tự lưu trữTrung cấpĐọc 43 phútCập nhật 2026-09-06

Di chuyển VPS sang nhà cung cấp mới mà không gây downtime

Mọi máy chủ đều di chuyển ít nhất một lần. Phần kỹ thuật là phần dễ — thất bại nằm ở những khoảng trống giữa ba chiếc đồng hồ không đồng bộ với nhau: DNS, dữ liệu, và các phiên đang diễn ra dở dang. Đây là cách để khép lại những khoảng trống đó vào một ngày thứ Ba do chính bạn chọn.

Di chuyển VPS sang nhà cung cấp mới mà không gây downtime
Trong trang này
  1. Ba chiếc đồng hồ, và vì sao “zero downtime” là mục tiêu sai
  2. Nhà cung cấp cũ giữ lại những gì sau khi bạn rời đi
  3. Đồng hồ TTL bắt đầu chạy từ một tuần trước khi di chuyển
  4. Chọn cấu hình cho máy mới, và những gì cần kiểm tra trước khi chốt
  5. Từng bước một
  6. Mail không di chuyển theo cùng phần còn lại
  7. Rollback mà không khiến mọi thứ tệ hơn
  8. Ngừng sử dụng: xoay vòng, xóa sạch, xác minh, rồi hủy
  9. Một dòng thời gian thực sự hiệu quả
  10. Câu hỏi thường gặp

Mọi máy chủ bạn đang chạy rồi cũng sẽ phải di chuyển ít nhất một lần. Nhà cung cấp tăng giá, hoặc bắt đầu đòi bạn gửi một loại giấy tờ mà bạn thà không gửi còn hơn, hoặc nhận một khiếu nại lạm dụng về một hàng xóm nào đó rồi null cả một dải /24 trong một buổi chiều. Câu hỏi chưa bao giờ là liệu bạn có di chuyển hay không — mà chỉ là liệu điều đó xảy ra vào một sáng thứ Ba do chính bạn chọn, hay vào một tối thứ Bảy do ai đó khác chọn hộ bạn.

Phần kỹ thuật không phải là phần khó. Sao chép tệp chỉ là rsync, và bạn đã biết điều đó rồi. Thứ khiến các cuộc di chuyển đi sai hướng chính là thời điểm: ba chiếc đồng hồ riêng biệt cùng chạy trong suốt quá trình di chuyển, chúng không đồng bộ với nhau, và mọi thất bại thực sự đều xảy ra trong những khoảng trống giữa chúng. Hướng dẫn này nói về những khoảng trống đó — TTL của DNS mà lẽ ra bạn nên hạ xuống từ một tuần trước, cơ sở dữ liệu mà bạn sao chép trong lúc nó vẫn đang được ghi vào, chứng chỉ chỉ tồn tại trên một chiếc máy mà bạn vừa mới tắt đi, và các thông tin xác thực mà nhà cung cấp cũ vẫn có thể đọc được suốt thời gian qua.

Các lệnh trong bài giả định cả hai đầu đều dùng Debian hoặc Ubuntu và một ứng dụng web có cơ sở dữ liệu, vì đó là thứ phần lớn mọi người đang di chuyển. Một Nextcloud, một game server, một bot hay một BTCPay instance đều theo cùng một dạng thức — chỉ có bước xử lý dữ liệu là khác biệt.

Ba chiếc đồng hồ, và vì sao “zero downtime” là mục tiêu sai

Một cuộc di chuyển không phải là một sự kiện đơn lẻ. Đó là ba chiếc đồng hồ bấm giờ chạy ở tốc độ khác nhau, và cả nghệ thuật này nằm ở việc ngăn chúng chồng lấn lên nhau một cách tệ hại:

  • Đồng hồ DNS. Kể từ thời điểm bạn đổi một bản ghi A, các resolver vẫn tiếp tục trả lời bằng địa chỉ cũ cho tới khi bản sao đã cache của chúng hết hạn. Bạn không kiểm soát được chiếc đồng hồ đó vào thời điểm chuyển đổi — bạn đã kiểm soát nó từ lúc bạn đặt TTL, nhiều ngày trước đó.
  • Đồng hồ dữ liệu. Bản sao dữ liệu gần nhất của bạn là một bức ảnh chụp lại một khoảnh khắc. Mọi thứ được ghi sau khoảnh khắc đó chỉ tồn tại trên máy cũ, và sẽ mất đi trừ khi bạn phát lại nó hoặc ngăn nó xảy ra.
  • Đồng hồ phiên làm việc. Các lượt tải lên đang dở dang, các WebSocket đang mở, một callback thanh toán sắp đến trong bốn mươi giây nữa từ một bên xử lý thanh toán vừa phân giải hostname của bạn hai phút trước. Những thứ này sẽ đáp xuống bất kỳ máy nào mà bên gửi đã phân giải được, chứ không phải máy mà bạn mong muốn.

Theo đuổi zero downtime theo đúng nghĩa đen nghĩa là phải giữ cho cả ba đồng hồ cùng chạy song song, và trên thực tế điều đó nghĩa là chạy ứng dụng trên hai máy chủ, cùng ghi vào hai cơ sở dữ liệu một lúc. Đó là một bài toán thực sự khó, và là bài toán sai cần giải cho một VPS đơn lẻ. Mục tiêu trung thực thì hẹp hơn nhiều và dễ đạt được hơn nhiều:

Không khách truy cập nào gặp lỗi, và không lượt ghi nào bị mất. Một khung chín mươi giây mà trang web vẫn hoạt động nhưng chỉ ở chế độ đọc thỏa mãn cả hai điều đó, và gần như không ai nhận ra. Một cuộc chuyển đổi trực tiếp không có khung bảo trì mà âm thầm đánh mất bốn mươi phút gửi biểu mẫu cuối cùng thì không thỏa mãn điều nào cả, và bạn sẽ biết được điều đó từ chính một khách hàng.

Vậy nên kế hoạch là: làm cho khung chỉ đọc ngắn nhất có thể, làm cho nó nhàm chán, và làm cho nó có thể đảo ngược được. Mọi thứ bên dưới đều phục vụ cho ba điều đó.

Nhà cung cấp cũ giữ lại những gì sau khi bạn rời đi

Phần này thường bị bỏ qua, và đó chính là lý do khiến nhiều người di chuyển ngay từ đầu, nên đáng để nói cho thật chính xác. Trong suốt thời gian máy chủ của bạn sống trên phần cứng của người khác, nhà cung cấp đó có đủ vị thế để thấy được:

  • Toàn bộ ổ đĩa. Trừ khi volume đã được mã hóa bằng LUKS và chỉ do một mình bạn mở khóa, hypervisor có thể đọc được từng byte của nó — khóa, token, nội dung cơ sở dữ liệu, tất tần tật. Ngay cả khi đã mã hóa, bộ nhớ của một VM đang chạy vẫn chứa khóa đã được mở.
  • Mọi thông tin xác thực mà máy đã dùng. Token API trong các tệp môi trường, mật khẩu SMTP, các bí mật RPC của wallet daemon, khóa SSH công khai của bạn, và nếu bạn từng dán một khóa riêng tư vào rescue console, thì còn nhiều hơn thế nữa.
  • Bất cứ thứ gì tài khoản yêu cầu. Một cái tên, một tấm thẻ, một địa chỉ, một số điện thoại để xác minh SMS, các địa chỉ IP mà bạn đã từng đăng nhập từ đó. Tập hợp đó không hề nhỏ đi khi bạn đóng tài khoản, và ở phần lớn các khu vực pháp lý, nhà cung cấp bị buộc phải giữ lại một phần trong số đó suốt nhiều năm.

Không có gì trong số này là đen tối cả — đó chỉ đơn giản là ý nghĩa của việc chạy một máy ảo trên phần cứng của người khác, ở bất cứ đâu, kể cả ở đây. Điều quan trọng là một cuộc di chuyển là điểm dứt điểm sạch sẽ duy nhất mà bạn có được. Máy mới bắt đầu với khóa mới, token mới và một IP mới; nếu bạn mang các bí mật cũ sang theo, bạn cũng mang luôn nguy cơ lộ lọt cũ sang theo cùng, và cú dứt điểm đó chỉ là hình thức.

Vậy nên hãy coi mọi bí mật trên máy cũ là đã bị lộ theo mặc định và cấp lại chúng trong quá trình di chuyển. Việc đó chỉ tốn của bạn một giờ, một lần duy nhất. Còn để dành làm sau, riêng lẻ, là việc mà chẳng ai từng thực sự bắt tay vào làm. Và nếu một phần lý do khiến bạn di chuyển chính là vì bản thân tài khoản đó là chỗ rò rỉ, thì việc trả tiền cho máy mới bằng Monero gắn với một tài khoản no-KYC chính là bước khiến cú dứt điểm đó trở nên thực chất chứ không chỉ mang tính tượng trưng — dù bạn cũng nên thành thật với chính mình về việc điều đó thực sự mang lại gì và không mang lại gì, đó lại là một chủ đề riêng.

Đồng hồ TTL bắt đầu chạy từ một tuần trước khi di chuyển

Time to live (TTL) là số giây mà một resolver được phép giữ bản ghi của bạn trước khi hỏi lại. Nếu bản ghi A của bạn có TTL mặc định là 3600, thì ngay tại thời điểm bạn đổi nó, một resolver vừa hỏi một giây trước đó vẫn sẽ tiếp tục gửi khách truy cập tới máy chủ cũ trong suốt năm mươi chín phút năm mươi chín giây tiếp theo. Với mức 86400 mà nhiều nhà đăng ký tên miền vẫn để mặc định, con số đó trở thành trọn một ngày.

Hãy kiểm tra xem thực sự bạn đang có gì — chứ không phải bạn nghĩ mình đã đặt gì:

dig +noall +answer example.com A
dig +noall +answer www.example.com A
dig +noall +answer example.com MX
dig +noall +answer example.com NS

Cột thứ hai trong mỗi câu trả lời chính là TTL, đang đếm ngược. Hãy hạ mọi bản ghi liên quan tới cuộc di chuyển xuống còn 300 giây, và làm việc đó trước cuộc chuyển đổi ít nhất gấp đôi khoảng thời gian TTL hiện tại: nếu bản ghi đang ở mức 86400, thì bản thân việc thay đổi đó sẽ mất một ngày mới hiển thị đồng nhất ở khắp nơi, đó chính là trò đùa mang tính đệ quy nằm ở ngay trung tâm của mọi cuộc di chuyển DNS.

Hai chi tiết hay gài bẫy người ta:

  • Các bản ghi NS có TTL riêng của chúng, thường là một mức khá dài, và nó được đặt ở nhà đăng ký tên miền chứ không phải trong zone của bạn. Điều đó chỉ quan trọng nếu bạn cũng đang đổi luôn cả nameserver — điều mà bạn nên tránh làm trong cùng tuần với việc chuyển máy chủ. Hãy đổi nhà cung cấp, ổn định lại, rồi mới đổi nhà cung cấp DNS nếu bạn muốn. Hai biến số, hai cuối tuần.
  • “Lan truyền DNS” không phải là một khái niệm có thật. Không có gì lan truyền cả; chỉ có cache hết hạn. Không hề có hàng đợi nào để chờ và cũng không có nút bấm nào đẩy bản cập nhật ra nhanh hơn. Đòn bẩy duy nhất là TTL, và tới thời điểm chuyển đổi thì nó đã được kéo từ trước rồi.

Trong lúc đang ở trong zone file, hãy ghi lại mọi bản ghi trỏ thẳng vào địa chỉ IP của máy chủ thay vì trỏ vào một tên miền. Thường sẽ có nhiều hơn bạn nhớ đúng một bản ghi: mail, webmail, một @ trơn, một staging cũ, bản ghi SPF có chứa một chuỗi ip4: literal, và bản ghi AAAA mà bạn thêm vào lần đầu có dải IPv6 rồi sau đó quên bẵng đi. Mỗi bản ghi trong số đó đều cần một kế hoạch, và AAAA chính là kiểu lỗi âm thầm kinh điển — bạn đổi bản ghi A, mọi thứ trông vẫn ổn từ laptop của bạn, còn mọi khách truy cập có IPv6 hoạt động thì vẫn tiếp tục đáp xuống một máy chủ mà bạn đã xóa sạch từ trước.

Chọn cấu hình cho máy mới, và những gì cần kiểm tra trước khi chốt

Hãy cưỡng lại ý muốn đặt mua đúng cấu hình bạn đang có hiện tại. Bạn đang mua theo những con số trên hóa đơn, chứ không phải theo những gì khối lượng công việc thực sự dùng đến. Hãy dành hai phút đo đạc trước đã:

# peak RAM actually in use, not allocated
free -m
# what has been paging, if anything
vmstat -s | grep -i swap
# real disk consumption, biggest first
du -xh --max-depth=2 / 2>/dev/null | sort -rh | head -20
# load relative to core count
uptime; nproc

Hai quy tắc kinh nghiệm này khá đáng tin. Nếu load average của bạn nằm dưới số lõi CPU và swap chưa từng bị động tới, thì máy không bị giới hạn bởi CPU hay bộ nhớ và bạn có thể chuyển ngang hoặc chuyển xuống một cấu hình nhỏ hơn. Nếu ổ đĩa đã dùng trên bảy mươi phần trăm, hãy chọn cấu hình máy mới theo thứ bạn sẽ cần trong một năm tới chứ không phải thứ bạn dùng hôm nay — mở rộng một volume sau này chẳng khác nào một cuộc di chuyển thu nhỏ, và bạn đang làm đúng một việc như vậy ngay lúc này.

Về phía chúng tôi thì điều đó ánh xạ khá rõ ràng: Pup (1 vCPU, 1 GB, 25 GB) chạy một trang tĩnh, một VPN hoặc một bot nhỏ; Cub (1 vCPU, 2 GB, 40 GB) là cấu hình nhỏ nhất chứa được một ứng dụng cùng cơ sở dữ liệu riêng của nó mà không phải paging; Scout (2 vCPU, 4 GB, 70 GB) là lựa chọn mặc định thoải mái cho một trang thật với lượng truy cập thật; Hunter (4 vCPU, 8 GB, 140 GB) trở lên là nơi container, CI hoặc nhiều dịch vụ trên cùng một máy bắt đầu thuộc về. Tất cả đều toàn NVMe với băng thông không giới hạn, nên việc vượt băng thông — một lý do phổ biến khiến người ta chuyển máy chủ ngay từ đầu — không còn là một biến số nữa. Toàn bộ các gói ở đây.

Sau đó, trước khi bạn chuyển dù chỉ một byte, hãy kiểm tra ba điều về chiếc máy bạn vừa được cấp. Mỗi điều trong số đó đều rẻ nếu làm bây giờ và đắt nếu làm sau khi đã chuyển đổi:

  • Độ uy tín của IP. Một địa chỉ tái chế mang lịch sử của người khác sẽ khiến mail của bạn bị từ chối và khách truy cập của bạn bị thách thức xác minh. Địa chỉ của chúng tôi được sàng lọc và phân loại theo mức rủi ro trước khi cấp phát, nhưng giờ đây dịch vụ đang chạy trên đó là của bạn, nên hãy tự kiểm tra lấy — phiên bản năm phút ở đây. Hãy làm việc này trước khi đổi bản ghi DNS, lúc mà câu trả lời vẫn chưa tốn của bạn thứ gì.
  • Reverse DNS. Nếu máy sẽ từng gửi mail, bản ghi PTR phải phân giải ra một hostname mà hostname đó lại phân giải ngược về đúng IP đó. rDNS tùy chỉnh có thể yêu cầu được; hãy xin ngay từ bây giờ để nó kịp ổn định trước lúc chuyển đổi.
  • Tuyến đường từ nơi người dùng của bạn đang ở. Một lượt mtr từ một máy ở khu vực người dùng của bạn cho biết nhiều điều về lựa chọn khu vực pháp lý hơn bất kỳ datasheet nào. Độ trễ bạn tự đo được luôn hơn độ trễ bạn tự đoán.

Từng bước một

  1. Hạ mọi TTL, nhiều ngày trước khi bạn định di chuyển

    Đây là bước đầu tiên vì nó là bước duy nhất có một khoảng thời gian chờ bắt buộc. Mọi thứ khác đều có thể làm xong trong một buổi chiều; riêng bước này thì không thể hối cho nhanh được, và bỏ qua nó chính là thứ biến một cuộc chuyển đổi năm phút thành một cuộc chuyển đổi hai ngày.

    Hãy đăng nhập vào nơi zone của bạn đang sống và đặt TTL thành 300 trên mọi bản ghi sẽ thay đổi: bản ghi A gốc, AAAA, www, mail, và bất cứ thứ gì khác đang trỏ tới một địa chỉ IP literal. Sau đó xác nhận lại từ bên ngoài, vì control panel và thực tế đôi khi không khớp nhau:

    dig +noall +answer example.com A @1.1.1.1
    dig +noall +answer example.com AAAA @1.1.1.1
    dig +noall +answer www.example.com A @8.8.8.8

    Con số đứng trước IN chính là TTL còn lại. Hãy truy vấn lại một phút sau đó: nó phải đang đếm ngược từ 300, chứ không phải từ một con số lớn hơn. Nếu nó vẫn đang đếm ngược từ 3600, giá trị cũ đang bị cache và bạn phải chờ nó hết hạn — đây chính xác là lý do vì sao việc này nên xảy ra vào ngày trừ bảy chứ không phải vào sáng ngày di chuyển.

    Hãy giữ TTL ở mức 300 trong suốt cuộc di chuyển và trong một tuần sau đó, để rollback của bạn cũng nhanh theo. Đặt nó về lại một mức hợp lý — 3600 là ổn — một khi máy cũ đã không còn nữa.

  2. Kiểm kê máy chủ cũ trước khi sao chép bất cứ thứ gì

    Bạn không di chuyển một ổ đĩa, bạn đang di chuyển một hệ thống đang chạy sống, và những phần người ta hay quên không bao giờ nằm trong /var/www. Đó là cron job chạy vào ngày mùng bốn hàng tháng, quy tắc firewall được thêm vào trong lúc xử lý một sự cố, gói phần mềm được cài từ một repository bên thứ ba hai năm trước. Hãy chụp lại trạng thái của máy dưới dạng văn bản, rồi sao chép văn bản đó sang cùng mọi thứ khác:

    mkdir -p /root/mig
    dpkg --get-selections > /root/mig/packages.txt
    systemctl list-units --type=service --state=running --no-pager > /root/mig/services.txt
    systemctl list-timers --all --no-pager > /root/mig/timers.txt
    crontab -l > /root/mig/cron-root.txt 2>/dev/null
    for u in $(cut -d: -f1 /etc/passwd); do crontab -lu "$u" 2>/dev/null | sed "s/^/[$u] /"; done > /root/mig/cron-users.txt
    ss -tlnp > /root/mig/listening.txt
    nft list ruleset > /root/mig/firewall.txt 2>/dev/null || iptables-save > /root/mig/firewall.txt
    cp -a /etc/hosts /etc/fstab /root/mig/
    du -xh --max-depth=2 / 2>/dev/null | sort -rh | head -40 > /root/mig/disk.txt

    Giờ hãy đọc listening.txt từng dòng một và giải trình cho mọi cổng. Tệp đó là câu trả lời dứt khoát cho câu hỏi “máy chủ này thực sự đang làm gì”, và câu trả lời đó thường xuyên gây bất ngờ — một metrics exporter, một bản staging bị bỏ quên, một cơ sở dữ liệu đang lắng nghe trên một giao diện công khai mà lẽ ra không bao giờ nên như vậy.

    Hãy viết danh sách loại trừ của bạn cùng lúc, để lượt đồng bộ đầu tiên không tốn cả giờ đồng hồ vào dữ liệu bạn không cần:

    cat > /root/mig/excludes <<'EOF'
    /dev
    /proc
    /sys
    /run
    /tmp
    /var/tmp
    /var/cache
    /var/lib/apt/lists
    /swapfile
    /var/lib/docker/overlay2
    /var/lib/mysql
    /var/lib/postgresql
    **/node_modules
    **/.cache
    EOF

    Lưu ý rằng các thư mục cơ sở dữ liệu bị loại trừ một cách có chủ đích. Chúng có bước riêng của mình, và sao chép chúng ở đây chính là sai lầm mà bước sáu tồn tại để ngăn chặn.

  3. Triển khai máy chủ mới và tăng cường bảo mật cho nó trước khi nó chứa bất cứ thứ gì

    Đặt mua máy, chọn vị trí và nếu có thể hãy chọn đúng phiên bản hệ điều hành chính giống máy cũ. Vừa đổi nhà cung cấp vừa đổi từ Debian 12 sang Debian 13 trong cùng một thao tác nghĩa là khi có gì đó hỏng, bạn sẽ không biết thay đổi nào gây ra nó. Hãy di chuyển trước, nâng cấp sau.

    Trước khi bất cứ thứ gì nhạy cảm đặt chân lên nó, hãy cho máy trải qua lượt tăng cường bảo mật mười phút: SSH chỉ dùng khóa, tắt đăng nhập root, firewall mặc định chặn tất cả, tự động cập nhật bảo mật. Việc đó chỉ tốn mười phút ngay bây giờ, còn nếu để sau mới lắp vào một dịch vụ đang sống thì thực sự rất phiền toái.

    Sau đó, hãy tạo một khóa chỉ tồn tại cho riêng cuộc di chuyển này, trên máy chủ cũ, để việc thu hồi quyền truy cập di chuyển sau này không bao giờ đồng nghĩa với việc phải đụng vào tài khoản đăng nhập của chính bạn:

    # on the OLD server
    ssh-keygen -t ed25519 -f /root/.ssh/id_migrate -C 'migration' -N ''
    cat /root/.ssh/id_migrate.pub

    Đặt khóa công khai đó vào /root/.ssh/authorized_keys trên máy chủ mới, rồi xác nhận chiều di chuyển — cũ đẩy sang mới, để thông tin xác thực đó sống trên chiếc máy bạn sắp rời bỏ và chết theo cùng nó:

    ssh -i /root/.ssh/id_migrate root@NEW_IP 'hostname; df -h /; free -m'

    Cuối cùng, hãy đặt IP mới vào /etc/hosts của máy chủ cũ dưới một cái tên như newbox. Mọi lệnh tiếp theo sau đó sẽ ngắn gọn hơn, và hữu ích hơn nữa là khó trỏ nhầm vào sai máy lúc một giờ sáng.

  4. Kiểm tra IP mới trước khi giao phó bất cứ thứ gì cho nó

    Giờ bạn đã có một địa chỉ chưa từng ai dùng cho dịch vụ của bạn trước đây, và đây là thời điểm cuối cùng mà việc phát hiện ra vấn đề với nó vẫn còn miễn phí. Ba lượt kiểm tra, năm phút:

    Blocklist. Hãy chạy địa chỉ đó qua các lượt kiểm tra đa-RBL — quy trình đầy đủ và cách đọc kết quả ở đây. Một lượt dính trên một danh sách chính sách như Spamhaus PBL là bình thường đối với một IP trung tâm dữ liệu và gần như không có ý nghĩa gì với traffic web. Một lượt dính trên SBL hoặc XBL mới là thật sự nghiêm trọng, và thời điểm để xử lý nó là ngay bây giờ, chứ không phải sau khi người dùng của bạn đã chuyển sang đó.

    Reverse DNS. Hãy kiểm tra xem địa chỉ đó hôm nay trả lời bằng gì:

    dig +short -x NEW_IP

    Nếu máy sẽ gửi mail, hãy yêu cầu bản ghi PTR bạn muốn và đảm bảo nó khớp với một hostname mà bản ghi A của hostname đó lại trỏ ngược về đúng IP này. Forward và reverse phải khớp nhau; một sự lệch pha còn tệ hơn cả một cái tên chung chung.

    Khả năng kết nối và tuyến đường. Hãy xác nhận các cổng bạn cần thực sự đang mở xuyên suốt từ đầu tới cuối, từ bên ngoài, thay vì mặc định cho rằng firewall của bạn là thứ duy nhất nằm trên đường đi:

    # from a third machine, or your laptop
    nc -vz NEW_IP 22
    mtr -rwc 20 NEW_IP

    Kết quả mtr là thứ đáng để giữ lại. Mất gói ở chặng cuối cùng mới quan trọng; mất gói ở một chặng trung gian thường chỉ là do một router hạ mức ưu tiên của ICMP và không có ý nghĩa gì cả. Nếu độ trễ từ khu vực người dùng của bạn tệ hơn đáng kể so với nhà cung cấp cũ, tốt hơn hết nên phát hiện ra điều đó ngay bây giờ, khi đổi ý vẫn chỉ tốn đúng một đơn hàng và không mất dữ liệu nào.

  5. Sao chép hệ thống tệp bằng rsync — và chạy dry-run trước

    Giờ là lượt truyền tải khối lượng lớn. Hãy làm việc đó theo hai lượt: một bản sao chép đầy đủ đầu tiên vài ngày trước, mất bao lâu cũng được, rồi tới các lượt delta ngắn sau đó chỉ chuyển những gì đã thay đổi. Luôn dry-run trước — kết quả in ra là một danh sách chính xác những gì sắp xảy ra, và chỉ cần đọc nó một lần đã cứu được nhiều cuộc di chuyển hơn bất kỳ thói quen nào khác ở đây.

    # on the OLD server, dry run
    rsync -aHAXx --numeric-ids --info=progress2 --dry-run \
      --exclude-from=/root/mig/excludes \
      -e 'ssh -i /root/.ssh/id_migrate' \
      /var/www/ root@newbox:/var/www/

    Sau đó chạy đúng lệnh đó nhưng bỏ --dry-run. Lặp lại việc này cho từng thư mục quan trọng: /etc một cách chọn lọc chứ không phải toàn bộ, /home, /srv, /opt, và bất cứ nơi nào ứng dụng của bạn thực sự lưu các tệp tải lên.

    Các flag này đều xứng đáng có mặt. -a giữ nguyên quyền, chủ sở hữu, timestamp và symlink; -H giữ lại hard link; -A-X mang theo ACL và extended attribute, đúng thứ thư mục uploads của bạn cần nếu có ai từng đặt chúng; -x ngăn rsync đi lạc sang các filesystem khác đã được mount. --numeric-ids là cái mà người ta hay bỏ sót và sau đó phải hối tiếc: nếu thiếu nó, rsync ánh xạ quyền sở hữu theo tên, và nếu www-data có UID khác nhau trên hai máy, mọi tệp sẽ đến nơi với chủ sở hữu sai theo một cách rất phiền phức để gỡ ra sau đó.

    Hai lời cảnh báo. Sao chép toàn bộ /etc lên một hệ thống đang chạy sẽ ghi đè cấu hình mạng, fstab và các SSH host key của máy mới — chỉ sao chép đúng phần cấu hình bạn cần, không phải cả thư mục. Và chỉ dùng --delete cho lượt cuối cùng mà thôi: nó đúng đắn khi cần làm cho máy mới khớp chính xác với máy cũ, nhưng lại có tính phá hủy nếu bạn đã tạo sẵn thứ gì đó ở phía đích.

    Khi lượt đầy đủ đầu tiên hoàn tất, hãy so sánh hai phía để biết chắc nó đã làm đúng như bạn nghĩ:

    du -sh /var/www
    ssh -i /root/.ssh/id_migrate root@newbox 'du -sh /var/www'
  6. Di chuyển cơ sở dữ liệu bằng một bản dump, không bao giờ bằng sao chép tệp trực tiếp

    Đây là bước quyết định xem cuộc di chuyển của bạn sẽ nhàm chán hay đáng nhớ. Thư mục dữ liệu của một cơ sở dữ liệu chỉ nhất quán khi máy chủ đã dừng. Sao chép nó khi đang chạy sống và bạn sẽ có được một tập tệp trông có vẻ ổn, truyền tải cũng ổn, nhưng khi khôi phục lại thành một cơ sở dữ liệu hỏng một cách âm thầm và vĩnh viễn — thường không hề báo lỗi cho tới nhiều tuần sau đó.

    Hãy dump nó cho đúng cách. Với MySQL hoặc MariaDB, --single-transaction chính là thứ cho bạn một bản chụp nhất quán mà không phải khóa toàn bộ:

    mysqldump --single-transaction --quick --routines --triggers --events \
      --default-character-set=utf8mb4 --databases appdb \
      | zstd -T0 > /root/mig/appdb.sql.zst

    Với PostgreSQL, định dạng tùy chỉnh (custom format) rất đáng dùng — nó nén được, và cho phép bạn khôi phục chọn lọc nếu cần:

    pg_dump -Fc -Z6 appdb > /root/mig/appdb.dump

    Chuyển nó sang máy mới và khôi phục:

    scp -i /root/.ssh/id_migrate /root/mig/appdb.sql.zst root@newbox:/root/
    # on the NEW server
    zstd -dc /root/appdb.sql.zst | mysql
    # postgres equivalent
    pg_restore -d appdb -j4 /root/appdb.dump

    Sau đó hãy xác minh, vì “khôi phục xong” và “dữ liệu đã có ở đó” là hai khẳng định khác nhau. Hãy so sánh số dòng trên các bảng quan trọng, ở cả hai phía:

    mysql -N -e "SELECT COUNT(*) FROM appdb.orders; SELECT COUNT(*) FROM appdb.users;"

    Có hai thứ hay ẩn mình trong các bản dump: bộ ký tự và collation, đây chính là nguồn gốc của các ký tự có dấu bị lỗi phông — nếu cơ sở dữ liệu cũ đang dùng utf8 thay vì utf8mb4, hãy chủ động quyết định xem liệu cuộc di chuyển này có phải cũng là thời điểm để sửa luôn điều đó không; và người dùng cùng quyền hạn của cơ sở dữ liệu, thứ mà mysqldump --databases không hề bao gồm. Hãy tạo lại tường minh user và mật khẩu của ứng dụng trên máy mới, rồi nhớ rằng chuỗi kết nối trong cấu hình của bạn cũng cần phải khớp theo.

    Nếu ứng dụng của bạn dùng SQLite, tệp đó chính là cơ sở dữ liệu và quy tắc tương tự vẫn áp dụng — đừng sao chép nó khi đang chạy sống. Hãy dùng sqlite3 app.db ".backup /root/mig/app.db", lệnh này lấy một bản sao nhất quán một cách an toàn.

  7. Khởi động stack và diễn tập nó phía sau một override bằng tệp hosts

    Máy chủ mới giờ đã có đủ tệp và dữ liệu. Hãy khởi động mọi thứ và kiểm thử nó dưới đúng hostname thật — trong khi phần còn lại của thế giới vẫn đang vui vẻ dùng máy cũ. Đây là mẹo giá trị nhất trong toàn bộ quy trình này và nó chỉ tốn đúng một dòng.

    Trên laptop của chính bạn, hãy thêm IP của máy chủ mới vào /etc/hosts (hoặc C:\Windows\System32\drivers\etc\hosts):

    203.0.113.10   example.com www.example.com

    Trình duyệt của bạn giờ sẽ phân giải tên miền thật về máy chủ mới, còn của tất cả những người khác thì không. Mọi URL đều đúng, mọi cookie domain đều khớp, mọi đường dẫn redirect và callback đều hoạt động đúng như cách chúng sẽ hoạt động sau khi chuyển đổi — đây chính xác là điều mà việc kiểm thử trên một subdomain tạm như new.example.com không thể bắt được, vì phân nửa những gì hay hỏng trong một cuộc di chuyển đều phụ thuộc vào hostname.

    Để kiểm tra nhanh một lượt duy nhất mà không cần sửa gì cả, curl có thể làm y hệt việc đó ngay trên dòng lệnh:

    curl -sSI --resolve example.com:443:203.0.113.10 https://example.com/
    curl -sS --resolve example.com:80:203.0.113.10 http://example.com/ -o /dev/null -w '%{http_code}\n'

    Hãy đi qua toàn bộ ứng dụng, không chỉ trang chủ: đăng nhập, gửi một biểu mẫu, tải lên một tệp, kích hoạt một mail reset mật khẩu, mở một trang admin, gọi tới endpoint mà một bên xử lý thanh toán vẫn gọi. Sau đó hãy đọc error log kể cả khi mọi thứ trông có vẻ ổn — các PHP extension bị thiếu, một file mode sai trên một thư mục cache, và một user cơ sở dữ liệu chưa tồn tại, tất cả đều hiện ra ở đó trước khi chúng hiện ra trên màn hình.

    Nhớ xóa dòng hosts đó đi sau khi xong việc. Ai cũng từng quên ít nhất một lần, rồi mất hai mươi phút tự hỏi vì sao rollback có vẻ như không hoạt động.

  8. Đưa TLS vào hoạt động trên máy mới trước khi đổi bất cứ thứ gì

    Chứng chỉ gắn với tên miền, không gắn với địa chỉ IP, nên không có gì trong một cuộc di chuyển làm mất hiệu lực một chứng chỉ bạn đã có sẵn. Thứ bị hỏng là việc cấp mới: thử thách HTTP-01 thông thường yêu cầu Let's Encrypt lấy về một tệp qua cổng 80 tại đúng tên miền đang được chứng thực, mà tên miền đó vẫn đang trỏ vào máy chủ cũ. Bài toán con gà quả trứng đó chính là toàn bộ cái khó, và có ba lối ra sạch sẽ.

    Sao chép các chứng chỉ hiện có. Đơn giản nhất và thường là đúng đắn nhất. Khóa riêng tư và chuỗi chứng chỉ di chuyển như bất kỳ tệp nào khác:

    rsync -aHAX -e 'ssh -i /root/.ssh/id_migrate' \
      /etc/letsencrypt/ root@newbox:/etc/letsencrypt/

    Máy chủ mới có thể phục vụ TLS hợp lệ ngay lập tức, và việc gia hạn tự động hoạt động trở lại ngay khi DNS trỏ về nó. Hãy xác nhận timer đã được bật ở đó: systemctl list-timers | grep certbot.

    Dùng một thử thách DNS-01. Chứng minh quyền kiểm soát tên miền thông qua một bản ghi TXT thay vì một request HTTP, nên nó hoạt động được ngay cả từ một máy chủ mà chưa có gì trỏ tới cả. Lý tưởng nếu bạn muốn có một chứng chỉ thực sự độc lập trên máy mới trước khi chuyển đổi, và là lựa chọn duy nhất cho một wildcard.

    Cấp sau khi đổi bản ghi. Vẫn hợp lệ, nhưng nó để lại một khoảng trống nơi trang web đã sống trên IP mới mà chưa có chứng chỉ, và với bất cứ thứ gì dùng HSTS thì đó không phải một cảnh báo mà khách truy cập có thể click bỏ qua được. Chỉ hợp lý cho một tên miền hoàn toàn mới mà chưa ai từng ghé thăm.

    Dù bạn chọn cách nào, hãy xác minh trực tiếp trên IP mới trước khi chuyển đổi, dùng đúng mẹo --resolve như trên:

    curl -sSI --resolve example.com:443:203.0.113.10 https://example.com/ | head -1
    echo | openssl s_client -connect 203.0.113.10:443 -servername example.com 2>/dev/null \
      | openssl x509 -noout -subject -dates

    Hãy kiểm tra ngày hết hạn và đảm bảo subject bao phủ mọi tên miền bạn phục vụ, kể cả www. Và nếu bạn dùng HSTS với một max-age dài, hãy coi chứng chỉ là thứ duy nhất bắt buộc phải đúng trước khi đổi bản ghi chứ không phải sau đó — header đó là một lời hứa bạn đã đưa ra từ trước với mọi khách truy cập quay lại.

  9. Chuyển đổi: đóng băng ghi, đồng bộ delta cuối, đổi bản ghi

    Mười phút làm việc thực sự, và là phần duy nhất có đồng hồ đếm. Hãy làm việc này vào buổi sáng, theo múi giờ của chính bạn, vào một ngày bạn không bận việc gì khác. Không bao giờ vào thứ Sáu.

    Đóng băng. Đưa ứng dụng cũ vào chế độ bảo trì hoặc chỉ đọc. Dừng các worker, các consumer của hàng đợi và các cron job — bất cứ thứ gì ghi dữ liệu mà không cần trình duyệt gắn kèm. Từ đây trở đi, không có gì mới được ghi trên máy cũ nữa, và đó chính là điều khiến mọi thứ sau bước này an toàn:

    # on the OLD server
    systemctl stop app-worker.service
    systemctl stop cron
    touch /var/www/maintenance.flag

    Delta cuối cùng. Thêm một lượt rsync nữa, lần này có --delete để phía đích khớp chính xác, và thêm một lượt dump nữa. Vì lượt đầu tiên đã hoàn tất từ nhiều ngày trước, lượt này chỉ chuyển rất ít và mất vài giây:

    rsync -aHAXx --numeric-ids --delete --exclude-from=/root/mig/excludes \
      -e 'ssh -i /root/.ssh/id_migrate' /var/www/ root@newbox:/var/www/
    mysqldump --single-transaction --quick --routines --triggers --events \
      --default-character-set=utf8mb4 --databases appdb | zstd -T0 \
      | ssh -i /root/.ssh/id_migrate root@newbox 'zstd -dc | mysql'

    Kiểm tra. So sánh số dòng ở cả hai phía, chạy thêm một lượt qua toàn bộ ứng dụng thông qua override bằng tệp hosts, rồi gỡ maintenance flag khỏi máy mới.

    Đổi bản ghi. Đổi bản ghi A sang IP mới. Đổi cả bản ghi AAAA nữa — đây là cách phổ biến nhất khiến một cuộc chuyển đổi chỉ thành công có nửa vời. Xác nhận từ một resolver mà bạn không kiểm soát:

    dig +short example.com A @1.1.1.1
    dig +short example.com AAAA @1.1.1.1

    Sau đó theo dõi cả hai máy. Traffic sẽ xuất hiện trên máy mới trong vòng một hai phút và nhạt dần khỏi máy cũ trong năm phút tiếp theo:

    tail -f /var/log/nginx/access.log        # on both, side by side

    Hãy để ứng dụng cũ ở chế độ bảo trì thay vì tắt hẳn nó đi. Một vị khách đến muộn chạm phải nó sẽ thấy một trang thông báo lịch sự thay vì một lỗi kết nối, và bạn vẫn giữ được máy đó sẵn sàng cho lượt rollback mà có lẽ bạn sẽ không cần dùng tới.

  10. Theo dõi trong một tuần, rồi ngừng sử dụng đúng cách

    Cuộc di chuyển chưa hoàn tất khi DNS đã phân giải xong. Nó chỉ thực sự hoàn tất khi trọn một chu kỳ thanh toán và cron trôi qua mà không có bất ngờ nào.

    Trong vài giờ đầu, hãy theo dõi tỷ lệ lỗi thay vì uptime — một máy chủ hoàn toàn có thể đang “up” mà vẫn trả về lỗi 500 cho một phần ba số request:

    journalctl -u nginx -u php8.4-fpm -f
    awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

    Sau đó hãy rà qua một danh sách ngắn, vì đây mới là những thứ thực sự hay hỏng sau một cuộc di chuyển và không thứ nào trong số đó tự lên tiếng báo trước: các cron job và systemd timer đang chạy trên máy mới (systemctl list-timers đối chiếu với bản kiểm kê bạn đã lấy ở bước hai); mail gửi đi có đến nơi và không rơi vào spam; các bản sao lưu theo lịch có đang trỏ vào máy chủ mới thay vì vẫn lưu trữ máy cũ; bất kỳ bên thứ ba nào có địa chỉ IP của bạn trong một allowlist — một bên xử lý thanh toán, một API, firewall của một đối tác; và job hàng tháng chỉ tự chứng minh vào ngày mùng một.

    Hãy để máy chủ cũ tiếp tục chạy, ở chế độ bảo trì, không động vào, trong ít nhất một tuần. Đó là rollback và bản sao tham chiếu của bạn, và nó đáng giá hơn nhiều so với vài đô la phải trả cho nó. Sau đó hãy đóng nó lại theo đúng thứ tự: xoay vòng mọi bí mật mà nó từng có thể đọc được, lấy một bản lưu trữ đã mã hóa cuối cùng gửi tới một nơi thứ ba, ghi đè lên các thư mục ứng dụng và cơ sở dữ liệu, chạy quy trình hủy hoặc cài lại của nhà cung cấp, và chỉ khi đó mới hủy — sau khi đã kiểm tra ngày gia hạn, vì thêm một tháng bảo hiểm rollback thường là một cuộc đổi chác khôn ngoan hơn.

    Cuối cùng, hãy đặt TTL trở lại mức 3600 giờ khi bạn không còn cần khả năng đảo ngược trong năm phút nữa, và cập nhật bất kỳ tài liệu nào bạn đang lưu giữ với địa chỉ mới. Bạn của tương lai, vào một lúc 2 giờ sáng nào đó sau này, sẽ cực kỳ biết ơn vì runbook khớp đúng với máy chủ thật.

Mail không di chuyển theo cùng phần còn lại

Nếu máy chủ cũ có gửi mail — kể cả chỉ để reset mật khẩu — hãy coi đó là một cuộc di chuyển thứ hai, chậm hơn, chạy song song với cuộc di chuyển đầu tiên. Khả năng gửi được mail (deliverability) là một hệ thống dựa trên uy tín, và uy tín đó gắn với địa chỉ IP và tên miền, chứ không gắn với phần mềm bạn vừa sao chép sang.

Có bốn bản ghi quyết định việc mail của bạn được đọc hay bị vứt bỏ, và ba trong số đó chứa những thứ sẽ thay đổi khi máy chủ thay đổi:

  • SPF liệt kê ai được phép gửi mail thay cho tên miền của bạn. Nếu bản ghi của bạn chứa một chuỗi ip4: literal, giờ nó đã sai rồi. Hãy thêm IP mới vào trước khi chuyển đổi và gỡ IP cũ ra một tuần sau đó — việc cho phép cả hai địa chỉ trong vài ngày chẳng tốn gì cả và giúp phủ kín giai đoạn chồng lấn.
  • DKIM ký thông điệp bằng một khóa riêng tư. Hãy sao chép khóa đó sang cùng với phần còn lại của cấu hình thì selector vẫn tiếp tục hoạt động. Nếu tạo một khóa mới thay vào đó, bạn sẽ phải công bố selector mới và chờ nó phát huy tác dụng, nên hãy cứ sao chép trừ khi bạn có lý do để không làm vậy.
  • DMARC cho bên nhận biết phải làm gì khi hai cơ chế trên thất bại. Nếu bạn đang ở mức p=reject, một bản ghi SPF bị hỏng trong lúc chuyển đổi không phải là một lời cảnh báo, đó là xóa mail âm thầm. Hãy cân nhắc hạ xuống p=none trong tuần di chuyển rồi đặt lại như cũ sau đó.
  • PTR chính là bản ghi ngược đã nói ở trên. Một IP mới sẽ có một bản ghi PTR chung chung cho tới khi bạn yêu cầu, và một số nhà cung cấp lớn từ chối thẳng thừng mail đến từ các tên reverse chung chung đó.

Kỳ vọng trung thực là: một IP hoàn toàn mới bắt đầu với con số uy tín bằng không, điều đó không giống với việc có uy tín tốt. Khối lượng gửi cần tăng dần qua nhiều ngày, chứ không phải trong vài giờ. Nếu mail là thứ sống còn với bạn, hãy giữ máy chủ cũ sống và tiếp tục gửi mail trong một tuần sau khi di chuyển thay vì chuyển hẳn trong một bước — và nếu nó sống còn ở cấp độ kinh doanh, một relay chuyên dụng là câu trả lời tốt hơn hẳn so với cả hai máy kia.

Rollback mà không khiến mọi thứ tệ hơn

Mục đích của một kế hoạch rollback không phải là để bạn mong đợi phải dùng đến nó. Mà là vì có sẵn một kế hoạch như vậy cho phép bạn chuyển đổi một cách bình tĩnh vào lúc 10 giờ sáng thay vì hồi hộp vào lúc 2 giờ sáng, và chính sự bình tĩnh mới là thứ thực sự ngăn ngừa sai sót.

Rollback của bạn rất đơn giản, và nó vẫn đơn giản đúng bằng khoảng thời gian cơ sở dữ liệu cũ vẫn còn là bản gốc có hiệu lực: đổi bản ghi A trở lại như cũ. Với TTL 300 giây bạn sẽ khôi phục xong trong năm phút. Khoảng cửa sổ đó — giữa lúc đổi bản ghi và lượt ghi thật đầu tiên chỉ tồn tại trên máy mới — chính là lượt hoàn tác miễn phí của bạn, và đó là lý do vì sao máy chủ cũ vẫn tiếp tục chạy, không bị động vào và không bị xóa, trong ít nhất một tuần.

Thứ phá hỏng tất cả là split-brain: các lượt ghi đáp xuống cả hai máy cùng lúc. Lúc này không cơ sở dữ liệu nào còn đúng cả, và việc đối chiếu chúng bằng tay còn tệ hơn bất kỳ khoảng downtime nào bạn từng cố tránh. Ba thói quen sau ngăn chặn hoàn toàn điều đó:

  • Đưa ứng dụng cũ vào chế độ chỉ đọc hoặc bảo trì ngay từ đầu khung thời gian, thay vì tin tưởng rằng DNS đã ngừng gửi traffic tới đó. DNS chỉ là một gợi ý; một dịch vụ đã dừng mới là một sự thật.
  • Sau khi đổi bản ghi, hãy theo dõi access log của máy chủ , không phải máy mới. Các request vẫn còn đến đó là những vị khách đến muộn của bạn, và khi luồng đó ngừng hẳn, cuộc di chuyển mới thực sự hoàn tất. tail -f /var/log/nginx/access.log là toàn bộ công cụ bạn cần.
  • Một khi bạn chấp nhận lượt ghi thật đầu tiên trên máy mới, việc rollback không còn là một thay đổi DNS nữa — mà là một lượt khôi phục dữ liệu. Hãy tự ý thức quyết định thời điểm bạn vượt qua ranh giới đó, và nói to lên nếu có hai người cùng làm việc này.

Hãy tự đặt cho mình một quy tắc dừng trước khi bắt đầu: nếu stack mới không phục vụ đúng trong vòng, giả sử, ba mươi phút, bạn sẽ trả bản ghi về như cũ, lấy lại buổi tối của mình, và sửa lỗi mà không có chiếc đồng hồ nào đang chạy cả. Các cuộc di chuyển đi sai hướng khi người ta cứ cố đẩy tiếp về phía trước vì quay đầu lại cảm giác như một thất bại. Không phải vậy đâu; đó là lựa chọn rẻ hơn, và nó chỉ khả dụng trong một khoảng thời gian giới hạn nghiêm ngặt.

Ngừng sử dụng: xoay vòng, xóa sạch, xác minh, rồi hủy

Một tuần sau khi chuyển đổi, máy chủ cũ là một bản sao đầy đủ, vẫn đang chạy, không ai trông coi, của toàn bộ dữ liệu của bạn, nằm trên hạ tầng mà bạn đã ngừng để tâm tới. Tại thời điểm đó, nó cũng chính là chiếc máy ít được vá lỗi nhất mà bạn sở hữu. Hãy hoàn tất công việc theo thứ tự sau:

  • Xoay vòng mọi thứ mà máy cũ từng đọc được. Bí mật của ứng dụng, token API, mật khẩu cơ sở dữ liệu, thông tin xác thực SMTP, bí mật ký webhook, mọi mật khẩu RPC của wallet. Hãy mặc định coi như đã bị lộ, vì bạn không thể chứng minh điều ngược lại. Nếu bạn đã tạo một khóa SSH riêng cho cuộc di chuyển này, đây là lúc rút các khóa đã cấp quyền cũ ra.
  • Lấy một bản lưu trữ cuối cùng — một snapshot restic hoặc Borg đã mã hóa gửi tới một đích không phải một trong hai máy đó. Bạn sẽ chỉ cần đến nó đúng một lần, sáu tuần sau, cho một tệp mà chẳng ai còn nhớ tới.
  • Ghi đè lên dữ liệu. Trên một VPS bạn không thể xác minh được vật lý phương tiện lưu trữ, nên hãy làm những gì bạn có thể: shred hoặc ghi đè lên các thư mục ứng dụng và cơ sở dữ liệu, rồi để quy trình cài lại hoặc hủy máy của nhà cung cấp chạy. Mã hóa dữ liệu lưu trữ (encryption at rest) ngay từ đầu chính là thứ khiến việc này trở nên rẻ; nếu không có nó, bạn đang phải dựa vào chính sách xóa dữ liệu của người khác.
  • Xác minh, rồi mới hủy. Hãy xác nhận máy mới đã phục vụ mọi thứ trong trọn một tuần, kể cả cron job hàng tháng mà chẳng ai để ý tới, và xác nhận không còn gì trên máy cũ vẫn còn phân giải được. Sau đó mới hủy — và hãy kiểm tra ngày gia hạn trước, vì trả thêm tiền cho một tháng dự phòng rollback thường khôn ngoan hơn là tiết kiệm tám đô la.

Hãy xóa chính tài khoản cũ sau cùng, và chỉ khi bạn thực sự chắc chắn. Các ticket hỗ trợ, hóa đơn và vài dịch vụ phụ bị quên lãng thường sống ở đó, và một tài khoản mà bạn không đăng nhập vào được là một nơi khá trớ trêu để phát hiện ra một bản ghi DNS mà bạn quên chưa chuyển đi.

Một dòng thời gian thực sự hiệu quả

Trải đều ra trong một tuần, chẳng có gì trong số này gây căng thẳng cả. Nhồi nhét vào một buổi tối duy nhất, thì tất cả đều gây căng thẳng.

  • Ngày −7. Hạ mọi TTL xuống 300. Kiểm kê máy chủ cũ. Đặt mua máy mới và kiểm tra IP, rDNS và tuyến đường của nó.
  • Ngày −5. Tăng cường bảo mật cho máy mới. Cài đặt stack. Chạy rsync đầy đủ lần đầu tiên, đây là lượt chậm nhất — mọi lượt sau đó chỉ chuyển phần delta.
  • Ngày −3. Khôi phục một bản dump cơ sở dữ liệu lên máy mới và khởi động ứng dụng lên. Kiểm thử toàn bộ thông qua một override bằng tệp hosts. Sửa những gì bị hỏng trong lúc chưa có gì thực sự đang bị đặt cược, vì rồi sẽ có thứ gì đó bị đặt cược thật.
  • Ngày −1. Cấp TLS trên máy chủ mới. Xác nhận chuỗi chứng chỉ và, nếu bạn dùng nó, xác nhận HSTS sẽ không biến một sai sót nhỏ thành thứ không thể click bỏ qua được. Thêm IP mới vào SPF. Kiểm tra lại xem mọi TTL đã thực sự hạ xuống chưa.
  • Ngày 0, buổi sáng. Bật chế độ bảo trì trên máy cũ. Đồng bộ delta lần cuối. Dump và khôi phục lần cuối. Kiểm tra số dòng. Đổi bản ghi A — và cả AAAA. Theo dõi cả hai access log.
  • Ngày +1 đến +7. Máy chủ cũ vẫn chạy, không động vào. Theo dõi log, mail và uy tín của IP mới. Nếu có thể, hãy để các job hàng tháng chạy ít nhất một lần.
  • Ngày +7. Xoay vòng bí mật, lưu trữ lần cuối, xóa sạch, xác minh, hủy.

Yếu tố dự báo tốt nhất cho một cuộc di chuyển nhàm chán là bước một đã xảy ra từ một tuần trước bước năm. Gần như mọi thứ đi sai trong một lần chuyển máy chủ đều là vì một TTL vẫn còn ở mức 86400 vào lúc mười một giờ đêm.

Câu hỏi thường gặp

Một cuộc di chuyển VPS có thực sự đạt được zero downtime không?

Zero downtime theo đúng nghĩa đen, với các lượt ghi được chấp nhận liên tục trên cả hai máy, đòi hỏi replication và một cơ sở dữ liệu dùng chung hoặc theo cụm — một bài toán thực sự khó, và là bài toán sai cần giải cho một máy chủ đơn lẻ. Thứ có thể đạt được, một cách đáng tin cậy, là không khách truy cập nào gặp lỗi và không lượt ghi nào bị mất: một khung chỉ đọc ngắn trong lúc đồng bộ lần cuối, với DNS đã ở TTL 300 giây từ trước để bản thân việc chuyển đổi chỉ mất vài phút. Trong thực tế đó là một đến năm phút hiện trang bảo trì, mà với gần như mọi trang web thì điều đó không khác gì zero downtime cả, và an toàn hơn rất nhiều so với phương án còn lại.

Lan truyền DNS thực sự mất bao lâu?

Không hề có việc lan truyền nào cả. Chẳng có gì được đẩy đi đâu hết — các resolver chỉ đơn giản cache bản ghi của bạn trong đúng số giây mà TTL của bạn quy định, rồi hỏi lại khi nó hết hạn. Nên câu trả lời trung thực là “chừng nào TTL đang có hiệu lực vào lúc bạn thực hiện thay đổi vẫn còn tồn tại”. Với một TTL là 300 được đặt từ một tuần trước, về cơ bản mọi người đều chuyển sang địa chỉ mới trong vòng năm phút. Với mức 86400 mà nhiều nhà đăng ký tên miền vẫn mặc định dùng, một số resolver vẫn tiếp tục gửi traffic tới máy chủ cũ trong trọn một ngày. Đây chính là lý do vì sao hạ TTL là bước một chứ không phải bước chín.

Tôi có thể giữ nguyên địa chỉ IP của mình khi đổi nhà cung cấp không?

Không, trừ khi bạn tự sở hữu dải địa chỉ đó và có thể nhờ nhà cung cấp mới announce nó, nghĩa là bạn phải là thành viên RIPE hoặc ARIN với phần cấp phát của riêng mình — khả thi với một công ty, chứ không phải với một máy chủ đơn lẻ. Với tất cả những người còn lại, một nhà cung cấp mới đồng nghĩa với một IP mới, và đó chính xác là lý do bạn cần kiểm tra độ uy tín và reverse DNS của nó trước khi chuyển đổi chứ không phải sau đó. Về phía chúng tôi, các địa chỉ đều được sàng lọc qua Spamhaus và hơn một trăm danh sách khác, đồng thời được cấp phát từ các pool đã phân loại theo mức rủi ro chứ không phải tái chế từ người dùng trước đó, nhưng tự kiểm tra chỉ mất năm phút và luôn luôn đáng để làm.

Tôi có nên dùng một disk image hay công cụ di chuyển của nhà cung cấp thay vì cách này không?

Nếu cả hai đầu đều cùng một nhà cung cấp và cùng một hypervisor, khôi phục từ image là ổn và nhanh hơn nhiều. Còn giữa các nhà cung cấp khác nhau thì đó thường là một cái bẫy: image mang theo cấu hình mạng, các kernel module, driver và các giả định phần cứng của máy cũ, và bạn sẽ mất trọn buổi tối để debug một hệ thống khởi động vào một cỗ máy không còn tồn tại nữa. Một bản cài đặt sạch cộng với một lượt sao chép dữ liệu và cấu hình được cân nhắc kỹ càng cho bạn một máy chủ mà bạn thực sự hiểu rõ, đồng thời bỏ lại mọi thứ rác đã tích tụ trên máy cũ. Di chuyển chính là cơ hội rẻ nhất mà bạn từng có để bỏ lại những thứ đó phía sau.

Còn một cơ sở dữ liệu đang liên tục bị ghi vào thì sao?

Có hai lựa chọn, xếp theo thứ tự công sức tăng dần. Lựa chọn đơn giản là khung chỉ đọc ở bước chín: một bản dump --single-transaction của một cơ sở dữ liệu bận rộn nhưng có kích thước bình thường chỉ mất vài giây tới vài phút, và một trang bảo trì trong khoảng thời gian đó là một cuộc đổi chác công bằng. Lựa chọn kỹ lưỡng hơn là replication — dựng máy chủ mới thành một replica từ nhiều ngày trước, để nó luôn đồng bộ, rồi promote nó lên trong khung thời gian chuyển đổi. Cách đó rút ngắn thời gian đóng băng xuống còn vài giây, đổi lại là một thiết lập thực sự phức tạp hơn. Chỉ chọn phương án thứ hai nếu phương án đầu không chấp nhận được, và đừng bao giờ ứng biến nó ngay trong đêm chuyển đổi.

Đổi nhà cung cấp có làm hại thứ hạng tìm kiếm của tôi không?

Tự bản thân việc đó thì không. Google lập chỉ mục theo hostname, không phải theo địa chỉ IP, và một cuộc di chuyển mà URL cùng nội dung vẫn giữ nguyên thì gần như vô hình đối với Google. Thứ thực sự gây tốn kém là những gì thường đi kèm với một cuộc di chuyển tệ: các trang trả về 5xx trong lúc crawler đang ghé thăm, một lỗi chứng chỉ, một robots.txt đến từ một bản staging còn chứa Disallow: / bên trong, hoặc các redirect âm thầm đổi dạng. Hãy kiểm tra robots.txt, các thẻ canonical của bạn và một vài URL thật ngay sau khi đổi bản ghi. Nếu trang web trả về đúng cùng những phản hồi trên IP mới như trên IP cũ, thì chẳng có gì cần phải khắc phục cả.

Chứng chỉ TLS của tôi có còn hoạt động trên máy chủ mới không?

Có — chứng chỉ được cấp cho tên miền, không phải cho địa chỉ IP, nên việc sao chép /etc/letsencrypt sang máy mới cho bạn một chứng chỉ hợp lệ ngay lập tức. Điểm phức tạp nằm ở việc gia hạn chứ không phải ở tính hợp lệ: một thử thách HTTP-01 cần tên miền trỏ vào đúng chiếc máy đang thực hiện gia hạn, nên cho tới khi bạn đổi bản ghi DNS, việc gia hạn ở đó sẽ thất bại. Hãy sao chép chứng chỉ trước khi chuyển đổi, đổi bản ghi, rồi xác nhận timer gia hạn chạy thành công trên máy chủ mới. Nếu bạn cần một chứng chỉ độc lập trước khi đổi bản ghi — hoặc một wildcard — hãy dùng một thử thách DNS-01 thay vào đó.

Triển khai VPS offshore trong khoảng một phút

Không KYC, thanh toán crypto, toàn NVMe. Chọn gói, thanh toán bằng Monero hoặc coin lớn bất kỳ, nhận quyền root sau khoảng 60 giây.

Fenrir đứng canh