、迁移背景说明

本次服务器硬件为 LGA‑775 架构老旧台式主机,双核处理器性能有限,整机内存 7.72GB,内存资源充裕。

最开始部署 Harbor 镜像仓库时,存储目录使用程序默认路径/var/lib/harbor,该目录归属系统盘分区。随着容器镜像、项目版本不断增加,镜像文件体积会持续上涨,系统盘存储空间较小,长期运行极易出现磁盘占满、服务器系统崩溃的问题。

服务器大容量数据分区路径为/opt/mirror,该目录原本用于存放 apt‑mirror 内网 APT 软件安装包镜像源。为充分利用该分区富余磁盘空间,决定将整套 Harbor 镜像仓库迁移至此目录下。

目录隔离设计思路

/opt/mirror 需要承载两套独立存储业务:

  1. apt‑mirror:deb 格式系统安装包内网镜像源

  2. Harbor:Docker 容器镜像仓库

为防止日常管理 APT 软件源的时候误删、混淆镜像仓库目录,Harbor 的数据目录、日志目录采用 Linux 隐藏文件夹进行隔离:

  • /opt/mirror/.harbor_data:容器镜像持久化存储目录

  • /opt/mirror/.harbor_log:Harbor 服务运行日志目录

普通可见目录专门管理 APT 软件源资源,隐藏目录存放容器仓库,两项业务互不干扰

为什么需要依托 Docker 容器运行 Harbor
Harbor 本身是由数据库、缓存、存储服务、反向网关等多个组件组成的容器化项目,所有服务依靠 Docker 容器启动运行;
磁盘文件夹只负责静态存放镜像文件、日志、数据库数据;容器才是真正读取、加载、运行仓库程序的载体;
迁移全程逻辑:容器生成完整仓库目录结构 → 备份原有全部数据 → 迁移文件至新分区 → 修改配置指向新路径 → 重启容器加载新路径内的镜像资源。
老旧 775 平台服务器额外优化要点
本机为双核 LGA‑775 处理器,CPU 性能偏弱,rsync 批量文件拷贝、apt‑mirror 软件源同步均会大量消耗 CPU 资源;
大批量文件拷贝任务可添加传输限速,降低 CPU 与磁盘 IO 负载:
bash
rsync -av --bwlimit=30 源路径 目标路径
两个 IO 密集型业务错峰运行,不要同时开启 APT 源同步与仓库迁移;
本机内存充足,硬件瓶颈仅为双核处理器,后续可以选购 65W 低功耗四核 Xeon L3360 进行硬件升级。
六、迁移最终收益
将容器镜像仓库脱离系统盘,规避镜像文件膨胀塞满系统分区的风险;
利用隐藏文件夹隔离 APT 软件源与 Docker 镜像仓库,避免日常操作误删;
数据独立存放至大容量磁盘分区,服务器后续重装系统不会丢失容器镜像资源,方便后期备份与维护

查看,harbor 镜像仓库,存储

du -lh --max-depth=1 /var/harbor_data.bak | sort -hr

shitou@shitou:~$ sudo du -lh --max-depth=1 /var | sort -hr
[sudo] password for shitou:
du: cannot access '/var/lib/docker/overlay2/27764b807de140f75d0d41362cda8711161ae08606cea879058166bf4a29aeff': No such file or directory
36G     /var
29G     /var/harbor_data.bak
5.5G    /var/lib
772M    /var/log
709M    /var/cache
3.6M    /var/crash
3.0M    /var/backups
64K     /var/tmp
32K     /var/spool
24K     /var/www
4.0K    /var/snap
4.0K    /var/opt
4.0K    /var/mail
4.0K    /var/local

镜像仓库

apt-mirror  ca_download  database  iso  job_logs  mirrors  redis  registry  secret
表格
目录	用途说明
registry	核心,存放所有 docker 镜像文件,一般占用磁盘最大
database	Harbor 数据库,存储项目、账号、配置元数据
redis	缓存、会话数据
job_logs	仓库任务运行日志
iso、mirrors	同步镜像、离线镜像资源

进入配置目录,查看有哪些配置文件,

cd harbor

root@shitou:/home/shitou/harbor# ls

common common.sh docker-compose.yml harbor-offline-installer-v2.13.1.tgz harbor-offline-installer-v2.13.1.tgz.1 harbor.v2.13.1.tar.gz harbor.yml harbor.yml.tmpl install.sh LICENSE prepare

root@shitou:/home/shitou/harbor#


root@shitou:/home/shitou/harbor# cat harbor.yml
# Configuration file of Harbor

# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
# 👇 已修改:hostname 改为目标IP 192.168.31.19
hostname: 192.168.31.19

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80

# https related config
https:
  # https port for harbor, default is 443
  port: 443
  # The path of cert and key files for nginx
  # 👇 已修改:证书路径匹配你生成的 IP 证书位置
  certificate: /etc/harbor/ssl/harbor.crt
  private_key: /etc/harbor/ssl/harbor.key
  # enable strong ssl ciphers (default: false)
  # strong_ssl_ciphers: false

# # Harbor will set ipv4 enabled only by default if this block is not configured
# # Otherwise, please uncomment this block to configure your own ip_family stacks
# ip_family:
#   # ipv6Enabled set to true if ipv6 is enabled in docker network, currently it affected the nginx related component
#   ipv6:
#     enabled: false
#   # ipv4Enabled set to true by default, currently it affected the nginx related component
#   ipv4:
#     enabled: true

# # Uncomment following will enable tls communication between all harbor components
# internal_tls:
#   # set enabled to true means internal tls is enabled
#   enabled: true
#   # put your cert and key files on dir
#   dir: /etc/harbor/tls/internal


# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433

# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: Harbor12345

# Harbor DB configuration
database:
  # The password for the user('postgres' by default) of Harbor DB. Change this before any production use.
  password: root123
  # The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained.
  max_idle_conns: 100
  # The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections.
  # Note: the default number of connections is 1024 for postgres of harbor.
  max_open_conns: 900
  # The maximum amount of time a connection may be reused. Expired connections may be closed lazily before reuse. If it <= 0, connections are not closed due to a connection's age.
  # The value is a duration string. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
  conn_max_lifetime: 5m
  # The maximum amount of time a connection may be idle. Expired connections may be closed lazily before reuse. If it <= 0, connections are not closed due to a connection's idle time.
  # The value is a duration string. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
  conn_max_idle_time: 0

# The default data volume
data_volume: /var/harbor_data

# Harbor Storage settings by default is using /data dir on local filesystem
# Uncomment storage_service setting If you want to using external storage
# storage_service:
#   # ca_bundle is the path to the custom root ca certificate, which will be injected into the truststore
#   # of registry's containers.  This is usually needed when the user hosts a internal storage with self signed certificate.
#   ca_bundle:

#   # storage backend, default is filesystem, options include filesystem, azure, gcs, s3, swift and oss
#   # for more info about this configuration please refer https://distribution.github.io/distribution/about/configuration/
#   # and https://distribution.github.io/distribution/storage-drivers/
#   filesystem:
#     maxthreads: 100
#   # set disable to true when you want to disable registry redirect
#   redirect:
#     disable: false

# Trivy configuration
#
# Trivy DB contains vulnerability information from NVD, Red Hat, and many other upstream vulnerability databases.
# It is downloaded by Trivy from the GitHub release page https://github.com/aquasecurity/trivy-db/releases and cached
# in the local file system. In addition, the database contains the update timestamp so Trivy can detect whether it
# should download a newer version from the Internet or use the cached one. Currently, the database is updated every
# 12 hours and published as a new release to GitHub.
trivy:
  # ignoreUnfixed The flag to display only fixed vulnerabilities
  ignore_unfixed: false
  # skipUpdate The flag to enable or disable Trivy DB downloads from GitHub
  #
  # You might want to enable this flag in test or CI/CD environments to avoid GitHub rate limiting issues.
  # If the flag is enabled you have to download the `trivy-offline.tar.gz` archive manually, extract `trivy.db` and
  # `metadata.json` files and mount them in the `/home/scanner/.cache/trivy/db` path.
  skip_update: false
  #
  # skipJavaDBUpdate If the flag is enabled you have to manually download the `trivy-java.db` file and mount it in the
  # `/home/scanner/.cache/trivy/java-db/trivy-java.db` path
  skip_java_db_update: false
  #
  # The offline_scan option prevents Trivy from sending API requests to identify dependencies.
  # Scanning JAR files and pom.xml may require Internet access for better detection, but this option tries to avoid it.
  # For example, the offline mode will not try to resolve transitive dependencies in pom.xml when the dependency doesn't
  # exist in the local repositories. It means a number of detected vulnerabilities might be fewer in offline mode.
  # It would work if all the dependencies are in local.
  # This option doesn't affect DB download. You need to specify "skip-update" as well as "offline-scan" in an air-gapped environment.
  offline_scan: false
  #
  # Comma-separated list of what security issues to detect. Possible values are `vuln`, `config` and `secret`. Defaults to `vuln`.
  security_check: vuln
  #
  # insecure The flag to skip verifying registry certificate
  insecure: false
  #
  # timeout The duration to wait for scan completion.
  # There is upper bound of 30 minutes defined in scan job. So if this `timeout` is larger than 30m0s, it will also timeout at 30m0s.
  timeout: 5m0s
  #
  # github_token The GitHub access token to download Trivy DB
  #
  # Anonymous downloads from GitHub are subject to the limit of 60 requests per hour. Normally such rate limit is enough
  # for production operations. If, for any reason, it's not enough, you could increase the rate limit to 5000
  # requests per hour by specifying the GitHub access token. For more details on GitHub rate limiting please consult
  # https://docs.github.com/rest/overview/resources-in-the-rest-api#rate-limiting
  #
  # You can create a GitHub token by following the instructions in
  # https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
  #
  # github_token: xxx

# 👇 保留原有完整的 jobservice 配置(已包含必要参数,避免 KeyError)
jobservice:
  # Maximum number of job workers in job service
  max_job_workers: 10
  # Maximum hours of task duration in job service, default 24
  max_job_duration_hours: 24
  # The jobLoggers backend name, only support "STD_OUTPUT", "FILE" and/or "DB"
  job_loggers:
    - STD_OUTPUT
    - FILE
    # - DB
  # The jobLogger sweeper duration (ignored if `jobLogger` is `stdout`)
  logger_sweeper_duration: 1 #days

notification:
  # Maximum retry count for webhook job
  webhook_job_max_retry: 3
  # HTTP client timeout for webhook job
  webhook_job_http_client_timeout: 3 #seconds

# Log configurations
log:
  # options are debug, info, warning, error, fatal
  level: info
  # configs for logs in local storage
  local:
    # Log files are rotated log_rotate_count times before being removed. If count is 0, old versions are removed rather than rotated.
    rotate_count: 50
    # Log files are rotated only if they grow bigger than log_rotate_size bytes. If size is followed by k, the size is assumed to be in kilobytes.
    # If the M is used, the size is in megabytes, and if G is used, the size is in gigabytes. So size 100, size 100k, size 100M and size 100G
    # are all valid.
    rotate_size: 200M
    # The directory on your host that store log
    location: /var/log/harbor

  # Uncomment following lines to enable external syslog endpoint.
  # external_endpoint:
  #   # protocol used to transmit log to external endpoint, options is tcp or udp
  #   protocol: tcp
  #   # The host of external endpoint
  #   host: localhost
  #   # Port of external endpoint
  #   port: 5140

#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY!
_version: 2.13.0

# Uncomment external_database if using external database.
# external_database:
#   harbor:
#     host: harbor_db_host
#     port: harbor_db_port
#     db_name: harbor_db_name
#     username: harbor_db_username
#     password: harbor_db_password
#     ssl_mode: disable
#     max_idle_conns: 2
#     max_open_conns: 0

# Uncomment redis if need to customize redis db
# redis:
#   # db_index 0 is for core, it's unchangeable
#   # registry_db_index: 1
#   # jobservice_db_index: 2
#   # trivy_db_index: 5
#   # it's optional, the db for harbor business misc, by default is 0, uncomment it if you want to change it.
#   # harbor_db_index: 6
#   # it's optional, the db for harbor cache layer, by default is 0, uncomment it if you want to change it.
#   # cache_layer_db_index: 7

# Uncomment external_redis if using external Redis server
# external_redis:
#   # support redis, redis+sentinel
#   # host for redis: <host_redis>:<port_redis>
#   # host for redis+sentinel:
#   #  <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3>
#   host: redis:6379
#   password:
#   # Redis AUTH command was extended in Redis 6, it is possible to use it in the two-arguments AUTH <username> <password> form.
#   # there's a known issue when using external redis username ref:https://github.com/goharbor/harbor/issues/18892
#   # if you care about the image pull/push performance, please refer to this https://github.com/goharbor/harbor/wiki/Harbor-FAQs#external-redis-username-password-usage
#   # username:
#   # sentinel_master_set must be set to support redis+sentinel
#   #sentinel_master_set:
#   # tls configuration for redis connection
#   # only server-authentication is supported
#   # mtls for redis connection is not supported
#   # tls connection will be disable by default
#   tlsOptions:
#     enable: false
#   # if it is a self-signed ca, please set the ca path specifically.
#     rootCA:
#   # db_index 0 is for core, it's unchangeable
#   registry_db_index: 1
#   jobservice_db_index: 2
#   trivy_db_index: 5
#   idle_timeout_seconds: 30
#   # it's optional, the db for harbor business misc, by default is 0, uncomment it if you want to change it.
#   # harbor_db_index: 6
#   # it's optional, the db for harbor cache layer, by default is 0, uncomment it if you want to change it.
#   # cache_layer_db_index: 7

# Uncomment uaa for trusting the certificate of uaa instance that is hosted via self-signed cert.
# uaa:
#   ca_file: /path/to/ca

# Global proxy
# Config http proxy for components, e.g. http://my.proxy.com:3128
# Components doesn't need to connect to each others via http proxy.
# Remove component from `components` array if want disable proxy
# for it. If you want use proxy for replication, MUST enable proxy
# for core and jobservice, and set `http_proxy` and `https_proxy`.
# Add domain to the `no_proxy` field, when you want disable proxy
# for some special registry.
proxy:
  http_proxy:
  https_proxy:
  no_proxy:
  components:
    - core
    - jobservice
    - trivy

# metric:
#   enabled: false
#   port: 9090
#   path: /metrics

# Trace related config
# only can enable one trace provider(jaeger or otel) at the same time,
# and when using jaeger as provider, can only enable it with agent mode or collector mode.
# if using jaeger collector mode, uncomment endpoint and uncomment username, password if needed
# if using jaeger agetn mode uncomment agent_host and agent_port
# trace:
#   enabled: true
#   # set sample_rate to 1 if you wanna sampling 100% of trace data; set 0.5 if you wanna sampling 50% of trace data, and so forth
#   sample_rate: 1
#   # # namespace used to differentiate different harbor services
#   # namespace:
#   # # attributes is a key value dict contains user defined attributes used to initialize trace provider
#   # attributes:
#   #   application: harbor
#   # # jaeger should be 1.26 or newer.
#   # jaeger:
#   #   endpoint: http://hostname:14268/api/traces
#   #   username:
#   #   password:
#   #   agent_host: hostname
#   #   # export trace data by jaeger.thrift in compact mode
#   #   agent_port: 6831
#   # otel:
#   #   endpoint: hostname:4318
#   #   url_path: /v1/traces
#   #   compression: false
#   #   insecure: true
#   #   # timeout is in seconds
#   #   timeout: 10

# Enable purge _upload directories
upload_purging:
  enabled: true
  # remove files in _upload directories which exist for a period of time, default is one week.
  age: 168h
  # the interval of the purge operations
  interval: 24h
  dryrun: false

# Cache layer configurations
# If this feature enabled, harbor will cache the resource
# `project/project_metadata/repository/artifact/manifest` in the redis
# which can especially help to improve the performance of high concurrent
# manifest pulling.
# NOTICE
# If you are deploying Harbor in HA mode, make sure that all the harbor
# instances have the same behaviour, all with caching enabled or disabled,
# otherwise it can lead to potential data inconsistency.
cache:
  # not enabled by default
  enabled: false
  # keep cache for one day by default
  expire_hours: 24

# Harbor core configurations
# Uncomment to enable the following harbor core related configuration items.
# core:
#   # The provider for updating project quota(usage), there are 2 options, redis or db,
#   # by default is implemented by db but you can switch the updation via redis which
#   # can improve the performance of high concurrent pushing to the same project,
#   # and reduce the database connections spike and occupies.
#   # By redis will bring up some delay for quota usage updation for display, so only
#   # suggest switch provider to redis if you were ran into the db connections spike around
#   # the scenario of high concurrent pushing to same project, no improvement for other scenes.
#   quota_update_provider: redis # Or db

配置文件释义

因为,/空间磁盘不够

 du -lh --max-depth=1 /var/ | sort -hr
du: cannot access '/var/lib/docker/overlay2/a920e2552e19e4a565f2b7d37477ba585a1c83bc8ae7bb8a8327bc80aa30c263': No such file or directory
36G     /var/
29G     /var/harbor_data.bak
5.8G    /var/lib
773M    /var/log
717M    /var/cache
3.6M    /var/crash
3.0M    /var/backups
64K     /var/tmp
32K     /var/spool
24K     /var/www
4.0K    /var/snap
4.0K    /var/opt
4.0K    /var/mail
4.0K    /var/local

报错原因

plaintext

du: cannot access ... overlay2 ... No such file or directory

docker 容器临时文件已经被销毁、目录残留失效,只是一条无关紧要的警告,不会影响最终统计结果,直接忽略即可。

2、重点数据

  1. /var 整体占用 36G

  2. /var/harbor_data.bak 就占了 29G

    这就是你系统盘空间压力巨大的元凶,54G 的系统盘光是这一份镜像备份就吃掉 29GB。

3、目录占用排行

表格

文件夹

占用大小

说明

/var/harbor_data.bak

29G

Harbor 镜像仓库备份,体积大头

/var/lib

5.8G

docker、软件运行数据

/var/log

773M

系统日志

/var/cache

717M

系统缓存文件

cp: cannot overwrite non‑directory '/var/harbor_data' with directory

  1. 最开始 /var/harbor_data普通文件,不是文件夹

  2. cp -r 文件夹,不能直接覆盖一个普通文件,直接报错

  3. rm -f 只能删除文件,无法删除文件夹,就算它之前是目录,‑f 参数也处理不掉,目录依旧残留在系统内,所以拷贝一直失败

2、中途按下 Ctrl+C 强制终止拷贝

执行拷贝指令之后,根目录磁盘占用已经达到 95%

系统盘空间快要耗尽,你手动快捷键中断了 cp 复制进程,防止硬盘直接爆满卡死服务器。

3、之后敲入正确删除指令

bash

sudo rm -rf /var/harbor_data
  • -r:递归,可以删除文件夹

  • -f:强制清除,忽略权限

    这条命令才真正把残留的旧目录 / 文件彻底删掉


最核心问题

/var 属于 54G 系统本地硬盘,空间马上塞满

harbor_data.bak 镜像备份体积很大,在系统盘内部复制文件夹,会瞬间占满剩余磁盘,引发系统卡死、docker 崩溃。


hitou@shitou:~$ df -h 查看容量大小
Filesystem                    Size  Used Avail Use% Mounted on
tmpfs                         791M  5.7M  786M   1% /run
/dev/mapper/ubuntu--vg-lv--0   54G   45G  6.1G  89% /
tmpfs                         3.9G     0  3.9G   0% /dev/shm
tmpfs                         5.0M     0  5.0M   0% /run/lock
tmpfs                         3.9G     0  3.9G   0% /run/qemu
/dev/sdb2                     2.0G  200M  1.6G  11% /boot
/dev/sda2                     1.4T  501G  773G  40% /opt/mirror
/dev/sda1                     492G  8.8G  458G   2% /home
tmpfs                         791M   16K  791M   1% /run/user/1000
shitou@shitou:~$ ls /opt/  进入这个挂载镜像的文件夹
cni/           containerd/    harbor_backup/ mirror/

这个先不管了,
shitou@shitou:~$ cd /opt/harbor_backup/
shitou@shitou:/opt/harbor_backup$ ls 
common  docker-compose.yml  harbor.yml  harbor.yml.tmpl  install.sh

sudo:使用管理员最高权限运行
mkdir:新建文件夹
-p:上级目录不存在也不会报错
/opt/mirror/.harbor_bak
文件夹建在1.4T 大盘里面
开头小数点 . = Linux 隐藏文件夹,网页浏览不会展示出来,不会干扰你文件同步

shitou@shitou:/opt/harbor_backup$ sudo mkdir -p /opt/mirror/.harbor_bak 

[sudo] password for shitou:
Sorry, try again.
[sudo] password for shitou:
shitou@shitou:/opt/harbor_backup$ ls
common  docker-compose.yml  harbor.yml  harbor.yml.tmpl  install.sh
shitou@shitou:/opt/harbor_backup$ pwd
/opt/harbor_backup
shitou@shitou:/opt/harbor_backup$ sudo rsync -av /var/harbor_data.bak /opt/mirror/.harbor_bak/
很长时间的复制。

正确操作思路

  1. 不要再在 /var 内部复制这份大容量备份

  2. 使用 rsync 把备份传到你的 1.4T 大盘隐藏目录

bash

rsync -av /var/harbor_data.bak /opt/mirror/.harbor_bak/
  1. 大盘存放好备份之后,需要还原的时候再拷贝回系统盘即可


简单区分 rm 参数

  • rm -f:仅删除单个文件,删不掉文件夹

  • rm -rf:强制删除文件、文件夹、嵌套目录,清理 harbor 数据必须用这条

后续复制完了的话,、在操作。,

先确认 rsync 数据同步全部结束

  1. 等待终端命令跑完、光标回到命令行,代表 Ubuntu 软件源镜像文件已经完整备份至 /opt/mirror/.harbor_bak

  2. 检查备份目录文件是否齐全

bash

ls /opt/mirror/.harbor_bak/

已关停正在运行的 tunasync 同步服务(防止抢占磁盘、文件冲突)

bash

# 停止工作节点
sudo systemctl stop tunasync-worker
# 停止管理节点
sudo systemctl stop tunasync-manager
# 杀掉后台残留进程
pkill tunasync

、已停止 Harbor 容器

bash

cd /home/shitou/harbor
sudo docker compose down

查看有哪些服务需要关停,查看所有活跃 systemd 服务

bash

systemctl list-units --type=service --state=running
shitou@shitou:~$ sudo systemctl stop tunasync-worker
[sudo] password for shitou:
shitou@shitou:~$ sudo systemctl stop tunasync-manager
shitou@shitou:~$ systemctl status tunasync-worker
○ tunasync-worker.service - Tunasync Worker Sync Node
     Loaded: loaded (/etc/systemd/system/tunasync-worker.service; disabled; preset: enabled)
     Active: inactive (dead)

Aug 08 02:22:19 shitou tunasync[6238]: [26-08-07 18:22:13][NOTICE] Stopping all the jobs
Aug 08 02:22:19 shitou tunasync[6238]: [26-08-07 18:22:15][WARNIN] SIGTERM failed to kill the job in 2s. SIGKILL sent
Aug 08 02:22:19 shitou tunasync[6238]: [26-08-07 18:22:15][WARNIN] failed syncing ubuntu-cdimage: killed by manager
Aug 08 02:22:19 shitou tunasync[6238]: [26-08-07 18:22:15][WARNIN] SIGTERM failed to kill the job in 2s. SIGKILL sent
Aug 08 02:22:19 shitou tunasync[6238]: [26-08-07 18:22:15][WARNIN] failed syncing ubuntu: killed by manager
Aug 08 02:22:19 shitou tunasync[6238]: [26-08-07 18:22:17][NOTICE] All the jobs are stopped
Aug 08 02:22:13 shitou systemd[1]: Stopping tunasync-worker.service - Tunasync Worker Sync Node...
Aug 08 02:22:22 shitou systemd[1]: tunasync-worker.service: Deactivated successfully.
Aug 08 02:22:22 shitou systemd[1]: Stopped tunasync-worker.service - Tunasync Worker Sync Node.
Aug 08 02:22:22 shitou systemd[1]: tunasync-worker.service: Consumed 1h 13min 43.383s CPU time, 159.3M memory peak, 0B memory swap peak.
shitou@shitou:~$ sudo systemctl stop docker
Stopping 'docker.service', but its triggering units are still active:
docker.socket
shitou@shitou:~$ sudo systemctl stop docker.socket
shitou@shitou:~$ systemctl list-units --type=service --state=running
  UNIT                             LOAD   ACTIVE SUB     DESCRIPTION
  containerd.service               loaded active running containerd container runtime
  cri-docker.service               loaded active running CRI Interface for Docker Application Container Engine
  cron.service                     loaded active running Regular background program processing daemon
  dbus.service                     loaded active running D-Bus System Message Bus
  fwupd.service                    loaded active running Firmware update daemon
  getty@tty1.service               loaded active running Getty on tty1
  kubelet.service                  loaded active running kubelet: The Kubernetes Node Agent
  ModemManager.service             loaded active running Modem Manager
  multipathd.service               loaded active running Device-Mapper Multipath Device Controller
  netdata.service                  loaded active running Netdata, X-Ray Vision for your infrastructure!
  NetworkManager.service           loaded active running Network Manager
  nginx.service                    loaded active running A high performance web server and a reverse proxy server
  nmbd.service                     loaded active running Samba NMB Daemon
  polkit.service                   loaded active running Authorization Manager
  rsyslog.service                  loaded active running System Logging Service
  smbd.service                     loaded active running Samba SMB Daemon
  ssh.service                      loaded active running OpenBSD Secure Shell server
  systemd-journald.service         loaded active running Journal Service
  systemd-journald@netdata.service loaded active running Journal Service for Namespace netdata
  systemd-logind.service           loaded active running User Login Management
  systemd-machined.service         loaded active running Virtual Machine and Container Registration Service
  systemd-networkd.service         loaded active running Network Configuration
  systemd-timesyncd.service        loaded active running Network Time Synchronization
  systemd-udevd.service            loaded active running Rule-based Manager for Device Events and Files
  udisks2.service                  loaded active running Disk Manager
  unattended-upgrades.service      loaded active running Unattended Upgrades Shutdown
  upower.service                   loaded active running Daemon for power management
  user@1000.service                loaded active running User Manager for UID 1000
  virtlockd.service                loaded active running libvirt locking daemon
  virtlogd.service                 loaded active running libvirt logging daemon
  wpa_supplicant.service           loaded active running WPA supplicant

Legend: LOAD   → Reflects whether the unit definition was properly loaded.
        ACTIVE → The high-level unit activation state, i.e. generalization of SUB.
        SUB    → The low-level unit activation state, values depend on unit type.

31 loaded units listed.
shitou@shitou:~$ top
top - 02:28:01 up  4:34,  4 users,  load average: 5.97, 7.26, 10.29
Tasks: 187 total,   1 running, 186 sleeping,   0 stopped,   0 zombie
%Cpu(s):  7.2 us, 27.1 sy,  0.0 ni, 12.5 id, 51.2 wa,  0.0 hi,  2.1 si,  0.0 st
MiB Mem :   7907.6 total,    152.9 free,    938.2 used,   7127.9 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.   6969.4 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 286046 root      20   0   16256   9712   7032 D  17.9   0.1   2:02.37 rsync
 286048 root      20   0  188544   7124   1916 S  16.6   0.1   2:03.68 rsync
     51 root       0 -20       0      0      0 I  10.3   0.0   8:08.36 kworker/1:1H-kblockd
     35 root      20   0       0      0      0 S   4.3   0.0   0:10.88 kcompactd0
  40124 netdata   20   0  875156 220288  24428 S   3.7   2.7  13:30.73 netdata
 193321 root      20   0       0      0      0 D   3.7   0.0   1:01.67 kworker/u4:8+flush-8:0
  40904 netdata   20   0  183532  11148   5880 S   2.7   0.1   8:45.76 apps.plugin
     52 root      20   0       0      0      0 S   2.3   0.0   4:12.78 kswapd0
   2884 root      20   0 1636188  59864  28000 S   2.3   0.7   7:43.95 kubelet
 233030 root      20   0       0      0      0 I   1.0   0.0   0:05.15 kworker/u4:0-flush-252:0
 288255 root      20   0       0      0      0 I   1.0   0.0   0:03.50 kworker/u4:2-ext4-rsv-conversion
  40964 netdata   20   0 1420924 108912  77436 S   0.7   1.3   4:18.43 go.d.plugin
     17 root      20   0       0      0      0 I   0.3   0.0   0:50.08 rcu_preempt
     36 root      25   5       0      0      0 S   0.3   0.0   1:15.98 ksmd
     84 root       0 -20       0      0      0 I   0.3   0.0   0:38.05 kworker/0:1H-kblockd
    347 root      19  -1   99788  51908  50500 S   0.3   0.6   5:57.22 systemd-journal
    815 message+  20   0   10464   6136   4600 S   0.3   0.1   0:58.29 dbus-daemon
    827 root      20   0   18076   8920   7796 S   0.3   0.1   0:20.11 systemd-logind
  39003 root      20   0   33996  12280  11192 S   0.3   0.2   0:03.16 systemd-journal
  40943 netdata   20   0  203992   7116   5876 S   0.3   0.1   0:17.96 sd-jrnl.plugin
  40981 netdata   20   0   15896   2408   1608 S   0.3   0.0   0:01.17 spawn-setns
 348224 netdata   20   0    4588   3500   2996 S   0.3   0.0   0:00.71 bash
      1 root      20   0   23156  14280   9496 S   0.0   0.2   0:49.00 systemd
      2 root      20   0       0      0      0 S   0.0   0.0   0:01.45 kthreadd
      3 root      20   0       0      0      0 S   0.0   0.0   0:00.00 pool_workqueue_release
      4 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/R-rcu_g
      5 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/R-rcu_p
      6 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/R-slub_
      7 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/R-netns
     10 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/0:0H-kblockd
     12 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/R-mm_pe
     13 root      20   0       0      0      0 I   0.0   0.0   0:00.00 rcu_tasks_kthread
     14 root      20   0       0      0      0 I   0.0   0.0   0:00.00 rcu_tasks_rude_kthread
     15 root      20   0       0      0      0 I   0.0   0.0   0:00.00 rcu_tasks_trace_kthread
     16 root      20   0       0      0      0 S   0.0   0.0   0:37.98 ksoftirqd/0
     18 root      rt   0       0      0      0 S   0.0   0.0   0:00.38 migration/0
     19 root     -51   0       0      0      0 S   0.0   0.0   0:00.00 idle_inject/0
     20 root      20   0       0      0      0 S   0.0   0.0   0:00.00 cpuhp/0
     21 root      20   0       0      0      0 S   0.0   0.0   0:00.00 cpuhp/1
     22 root     -51   0       0      0      0 S   0.0   0.0   0:00.00 idle_inject/1
     23 root      rt   0       0      0      0 S   0.0   0.0   0:00.72 migration/1
     24 root      20   0       0      0      0 S   0.0   0.0   0:08.53 ksoftirqd/1
     26 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/1:0H-events_highpri
     27 root      20   0       0      0      0 S   0.0   0.0   0:00.00 kdevtmpfs
     28 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/R-inet_
     29 root      20   0       0      0      0 S   0.0   0.0   0:00.01 kauditd
     30 root      20   0       0      0      0 S   0.0   0.0   0:00.01 khungtaskd
     32 root      20   0       0      0      0 S   0.0   0.0   0:00.00 oom_reaper
     34 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 kworker/R-write
     38 root      39  19       0      0      0 S   0.0   0.0   0:00.12 khugepaged

然后关停,

先识别列表里所有会读写硬盘、干扰 rsync 迁移的服务

🔴 最高优先级,必须关闭(容器、文件共享、实时监控)

  1. containerd.service:容器运行时底层服务,docker/k8s 依靠它读写磁盘

  2. cri‑docker.service:k8s 对接 docker 的接口

  3. kubelet.service:kubernetes 节点代理,会持续读写容器磁盘

  4. smbd.servicenmbd.service:Samba 网盘服务,随时读写 /opt/mirror 硬盘

  5. netdata.service:实时资源监控,不停写入磁盘日志、采集磁盘 IO

🟡 次要后台读写服务,迁移期间临时关停

  1. cron.service:定时任务,防止中途触发备份、自动脚本读写硬盘

  2. nginx.service:网页服务,避免站点缓存写入磁盘

  3. fwupd.service:固件自动更新服务

# 1.关闭k8s容器相关整套服务
sudo systemctl stop kubelet
sudo systemctl stop cri-docker
sudo systemctl stop containerd

# 2.关闭samba网盘(最容易占用你的/opt/mirror磁盘)
sudo systemctl stop smbd nmbd

# 3.关闭监控、定时任务、web服务
sudo systemctl stop netdata
sudo systemctl stop cron
sudo systemctl stop nginx
sudo systemctl stop fwupd

、修改 Harbor 配置,把存储路径更换到大容量硬盘

  1. 编辑主配置文件

bash

nano harbor.yml
  1. 找到 data_volume 参数

yaml

#旧路径
data_volume: /var/harbor_data
#修改为你的大盘路径
data_volume: /opt/mirror/harbor_data
  1. 保存退出编辑器


把刚刚 rsync 备份好的数据迁移到新工作目录

bash

#新建harbor‑data文件夹
sudo mkdir -p /opt/mirror/harbor_data
#把备份内全部镜像数据复制过来
sudo rsync -av /opt/mirror/.harbor_bak/ /opt/mirror/harbor_data/

从新,修改镜像仓库存储地址,

/opt/mirror 为内网 APT 软件包镜像站根目录,用来存放系统 deb 安装包资源。

为充分利用该分区磁盘空间,将 Docker‑Harbor 容器镜像仓库部署在此目录内;

为防止 APT 镜像目录与容器仓库目录发生混淆、误删,Harbor 的数据目录、日志目录采用 Linux 隐藏文件夹进行隔离,日常浏览目录时仅展示 APT 镜像业务文件夹,隐藏目录不会被直接列出,两类业务互不干扰。

完整执行步骤

bash

# 清理之前创建的普通仓库数据目录
sudo rm -rf /opt/mirror/harbor_data

# 创建隐藏格式的仓库数据目录、日志目录
sudo mkdir -p /opt/mirror/.harbor_data
sudo mkdir -p /opt/mirror/.harbor_log

# 迁移原有容器镜像备份数据
sudo rsync -av /opt/mirror/.harbor_bak/ /opt/mirror/.harbor_data/

# 迁移旧日志文件
sudo rsync -av /opt/mirror/harbor_log/ /opt/mirror/.harbor_log/

# 删除已经迁移完毕的旧日志文件夹
sudo rm -rf /opt/mirror/harbor_log

# 赋予目录读写权限,保证容器正常读写文件
sudo chmod -R 777 /opt/mirror/.harbor_data
sudo chmod -R 777 /opt/mirror/.harbor_log

# 使用管理员权限编辑配置文件
sudo nano ~/harbor/harbor.yml

配置文件关键参数

yaml

data_volume: /opt/mirror/.harbor_data

log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200M
    location: /opt/mirror/.harbor_log

编辑完成后保存退出,重载配置并启动服务

bash

sudo ./install.sh
docker compose up -d
  • /opt/mirror:内网 APT 软件包镜像站,存放 apt‑mirror、iso、mirrors 等可见业务目录

  • /opt/mirror/.harbor_data:Docker 容器镜像仓库存储目录(隐藏)

  • /opt/mirror/.harbor_log:Harbor 服务运行日志目录(隐藏)

将备份镜像数据完整还原至新隐藏目录

sudo rsync -av /opt/mirror/.harbor_bak/ /opt/mirror/.harbor_data/

停止了很多服务,

sudo systemctl stop tunasync-worker
  141  sudo systemctl stop tunasync-manager
  142  systemctl status tunasync-worker
  143  sudo systemctl stop docker
  144  sudo systemctl stop docker.socket
  145  systemctl list-units --type=service --state=running
  146  top
  147  sudo systemctl stop kubelet
  148  sudo systemctl stop cri-docker
  149  sudo systemctl stop containerd
  150  sudo systemctl stop netdata
  151  sudo systemctl stop cron
  152  sudo systemctl stop nginx
  153  sudo systemctl stop fwupd
  154  lsof +D /opt/mirror
  155  history

故障移步其他文章,

重载 Harbor 配置、启动容器

bash

#执行安装脚本加载新配置
sudo ./install.sh
#后台启动整套harbor服务
docker compose up -d

校验服务是否正常运行

bash

#查看启动的docker容器
docker ps
#查看harbor日志排查报错
docker logs -f harbor-core

镜像仓库迁移完成之后,重启软件源同步服务

bash

sudo systemctl start tunasync-manager
sudo systemctl start tunasync-worker

💡整体流程总结

等待 rsync 同步完成 → 关闭源同步服务 → 关停 Harbor → 修改存储路径配置 → 迁移镜像数据 → 重载配置启动 Harbor → 重启 tunasync 同步