担心 Harbor 数据丢失?谈谈 Harbor 的备份和恢复方法。
????????????博主介绍:大家好!我是李大白,一名运维容器运维工程师,热爱分享知识????
????擅长领域:云原生、数据库、自动化运维
????????如果本文章对小伙伴们有帮助的话,????关注+????????点赞+????评论+????收藏!
????如果在文章描述时如有错,恳请各位大佬指正,在此感谢!!!
???? 落叶而知秋,博闻而强识!
???? 精品专栏:Harbor大白话(企业级)
前言
备份指将数据复制一份或多份副本并将其存放到其他地方,当系统发生故障导致数据丢失时,可以通过这些副本恢复到之前的状态。
由此可见,备份和恢复都是围绕数据进行的。Harbor 备份的前提是了解 Harbor 中有哪些数据需要备份。
一、Harbor中的数据
Harbor 所依赖的数据可分为两大类:临时数据和持久化数据。
1.1 临时数据
在 Harbor 安装期间通过配置文件生成的数据,主要是 Harbor 组件所依赖的配置文件和环境变量。这些数据通常在 Harbor 安装目录的 common 目录下(如果 Harbor 是通过源代码安装的,则这些数据在源码目录的“make/common”目录下),在 Harbor 各组件启动时会被挂载到对应的容器中。虽然临时数据对服务的顺利运行至关重要,但是安装程序每次都会读取 Harbor 配置文件重新生成一份临时数据,所以我们仅需备份配置文件即可,不必将整个 common 目录全部备份。
1.2 持久化数据
存放在数据目录配置项下(即配置文件中 data_volume 项所配置的值),这些数据主要包括 Harbor 的数据库数据、Artifacts 数据、Redis 数据、Chart 数据,以及 Harbor 各个组件所依赖的运行时数据
data目录包含的文件夹和相应的作用如下。
- ca_download:存放用户访问Harbor时所需的CA。
- cert:Harbor启动HTTPS服务时所需的证书和密钥。
- chart_storage:存放Helm v2版本的Chart数据。
- database:存放数据库的目录,Harbor、Clair和Notary数据库的数据都在此目录下。
- job_logs:存放JobService的日志信息。
- redis:存放Redis数据。
- registry:存放OCI Artifacts数据(对于大部分用户来说是镜像数据)。
- secret:存放Harbor内部组件通信所需的加密信息。
- trivy-adapter:存放Trivy运行时相关的数据。
注意:
Harbor在启动时需要挂载这些目录下的文件,在Harbor各组件的容器中除了log容器(依赖logrotate,必须以root权限运行),其他容器都是以非root用户身份运行的,这些文件的用户组信息及权限信息与其在容器中的信息不匹配,在容器中就会发生读取权限相关的错误。
所以在主机上需要将这些目录和文件设置成容器的指定用户和用户组,这些文件的用户和权限信息主要有如下两类。
- 数据库和Redis:以999:999的用户组运行容器,即harbor-db组件和harbor-redis组件;
- Harbor的其他容器:以10000:10000的用户组运行容器;
还原后的数据一定要与备份时保持一致。许多用户在恢复数据后无法启动Harbor,而且日志里同时会有文件权限相关的错误信息,这极有可能就是备份数据的文件权限不正确导致的。
二、Harbor备份
2.1 创建备份目录
用来存放harbor的备份文件
$ mkdir -p /data/backup/harbor-backup/
2.2 备份Harbor安装目录
我的harbor是安装在/app/harbor下
$ cp /app/harbor /data/backup/harbor-backup/harbor
2.3 备份Harbor data
1.x.x版本的数据默认是存放在/data下,2.x.x默认是存放在安装目录的data目录下,如果不知道数据存放的位置,可打开harbor的配置文件harbor.yml中data_volume的值查看。
- 查看数据存放位置
$ grep data_volume /app/harbor/harbor.yml
data_volume: /data
- 备份data数据
$ cp /data /data/backup/harbor-backup/data
2.4 备份外部存储(可选)
如果使用了外部的数据库,如果使用了外部的数据库、Redis或者块存储,则需要参考所使用的外部存储提供的备份方案来备份其数据。
三、Harbor的恢复
使用前面备份的文件来恢复harbor中的数据,恢复方法就是跟备份相反。
3.1 停止Harbor
$ cd /app/harbor # 一定要进行harbor的安装目录
$ docker-compose down
3.2 删除当前的Harbor目录
$ rm -rf /app/harbor
3.3 恢复harbor安装目录
$ cp /data/backup/harbor-backup/harbor /app/harbor
3.4 恢复data目录
$ cp /data/backup/harbor-backup/data /data
3.5 重启Harbor
$ cd /app/harbor # 进入到安装目录
$ docker-compose up -d
四、基于shell单独备份Harbor中的镜像(扩展)
在实际的业务环境下,Harbor中的临时数据、配置数据相对都是较小的。而harbor中的镜像才是最占用磁盘空间的,如果也将镜像备份到harbor服务的主机上,将会对harbor发服务主机造成非常大的压力,影响harbor服务的稳定性。
本处使用另外一台主机来专门备份Harbor中的镜像文件。下面的操作都是在另外一台主机操作。
4.1 安装docker
安装docker服务,用于从harbor下载镜像。
- 配置repo镜像源
$ yum install -y yum-utils device-mapper-persistent-data lvm2
$ yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
$ sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
$ yum clean all && yum makecache
- 下载docker
$ yum install -y docker-ce
- 启动docker服务
$ systemctl enable --now docker.service
- 创建docker配置文件
在docker配置文件中指定harbor的服务地址。
$ cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": ["https://xcg41ct3.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"], # 驱动器
"insecure-registries": ["192.168.2.250:443"], # harbor的安全加密地址
"registry-mirrors": ["https://3hjcmqfe.mirror.aliyuncs.com"], # 镜像加速
"log-driver": "json-file",
"log-opts": {
"max-size": "500m"
}
}
EOF
- 重启docker
$ systemctl restart docker
4.2 编写Shell脚本(1.x.x)版本
$ cat <<EOF > harbor-imagebackup.sh
#!/bin/bash
Harbor_IP=192.168.2.250 #Harbor主机IP
Harbor_Port=443 #连接Harbor的端口号
Harbor_User=admin #登录Harbor的用户
Harbor_Passwd=Harbor12345 #登录Harbor的用户密码
Images_File=harbor-images-`date '+%Y-%m-%d'`.txt #镜像清单文件
Harbor_backlog=harbor-back-`date '+%Y-%m-%d'`.log #日志文件
Tar_File=/backup/Harbor-backup/ #镜像tar包存放路径
###【】调用API接口获取Harbor中所有仓库的所有镜像及镜像的所有标签(tag):
#获取Harbor中所有的项目(含私有项目)
Project_List=`curl -u $Harbor_User:$Harbor_Passwd -X GET http://$Harbor_IP:$Harbor_Port/api/projects | grep name | awk '/"name": /' | awk -F '"' '{print $4}'`
#获取项目下所有的镜像名称与标签:
for Project in $Project_List;do
Image_Names=`curl -u $Harbor_User:$Harbor_Passwd -X GET http://$Harbor_IP:$Harbor_Port/api/search?q=$Project | grep "repository_name" | awk -F "\"" '{print $4}'`
for Image in $Image_Names;do
Image_Tags=`curl -u $Harbor_User:Harbor_Passwd -X GET http://$Harbor_IP:$Harbor_Port/api/repositories/$Image/tags | awk '/"name": /' | awk -F '"' '{print $4}'`
for Tag in $Image_Tags;do
echo "$Harbor_IP:$Harbor_Port/$Image:$Tag" | grep -v Base | grep -v Image >> $Images_File
done
done
done
###使用docker从镜像文件中下载镜像——将下载的镜像进行打包保存——删除下载到本地的镜像——将封装好的镜像包移动到备份目录
Image_tags=$(uniq $Images_File)
for image_tag in $Image_tags;do
image_Name=$(echo $image_tag | awk -F/ '{print $3}' | awk -F: '{print $1}')
image_Lable=$(echo $image_tag | awk -F/ '{print $3}' | awk -F: '{print $2}')
docker pull $image_tag
docker save $image_tag -o $image_Name-$image_Lable.tar
docker rmi $image_tag
mv $image_Name-$image_Lable.tar $Tar_File
done
EOF
$ chmod +x harbor-imagebackup.sh
4.3 编写Shell脚本(2.x.x版本)
Harbor2版本和1版本的API调用是不同的,所以脚本也会有变化
$ cat <<EOF > harbor-imagebackup.sh
#!/bin/bash
Harbor_Address=192.168.2.250:443 #Harbor主机地址
Harbor_User=admin #登录Harbor的用户
Harbor_Passwd=Harbor12345 #登录Harbor的用户密码
Images_File=harbor-images-`date '+%Y-%m-%d'`.txt #镜像清单文件
Tar_File=/backup/Harbor-backup/ #镜像tar包存放路径
set -x
# 获取所有镜像清单
Project_List=$(curl -u $Harbor_User:$Harbor_Passwd -H "Content-Type: application/json" -X GET $Harbor_Address/api/v2.0/projects -k | python -m json.tool | grep name | awk '/"name": /' | awk -F '"' '{print $4}')
for Project in $Project_List;do
Image_Names=$(curl -u $Harbor_User:$Harbor_Passwd -H "Content-Type: application/json" -X GET $Harbor_Address/api/v2.0/projects/$Project/repositories -k | python -m json.tool | grep name | awk '/"name": /' | awk -F '"' '{print $4}')
for Image in $Image_Names;do
Image_Tags=$(curl -u $Harbor_User:$Harbor_Passwd -H "Content-Type: application/json" -X GET $Harbor_Address/v2/$Image/tags/list -k | awk -F '"' '{print $8}')
for Tag in $Image_Tags;do
echo "$Harbor_Address/$Image:$Tag" >> harbor-images-`date '+%Y-%m-%d'`.txt
done
done
done
###使用docker从镜像文件中下载镜像——将下载的镜像进行打包保存——删除下载到本地的镜像——将封装好的镜像包移动到备份目录
Image_tags=$(uniq $Images_File)
for image_tag in $Image_tags;do
image_Name=$(echo $image_tag | awk -F/ '{print $3}' | awk -F: '{print $1}')
image_Lable=$(echo $image_tag | awk -F/ '{print $3}' | awk -F: '{print $2}')
docker pull $image_tag
docker save $image_tag -o $image_Name-$image_Lable.tar
docker rmi $image_tag
mv $image_Name-$image_Lable.tar $Tar_File
done
EOF
$ chmod +x harbor-imagebackup.sh
4.4 执行脚本
选择对应版本的脚本来执行
$ ./harbor-imagebackup.sh
执行完成会在脚本文件所在的目录有备份日志可查看。
4.5 添加计划任务
添加计划任务进行定时备份
$ crontable -e
30 * * * 3 ./harbor-imagebackup.sh
推荐阅读
-
[【科普来了】一文读懂PE:什么是PE,PE怎么用?......- I. 什么是 PE? PE的英文全称是Preinstallation Environment,翻译过来就是预装环境。有了这个名字就好理解了,可以直接说它是一个预装的、微型的或精简版的系统。它的体积非常小,大多数 PE 通常只有一两百兆,通常我们可以把它安装在 U 盘或移动硬盘上,随身携带,在任何电脑上启动它。无需依赖电脑上的原始系统。 二、PE 可以做什么? 网上的 PE 工具大多是由很多喜欢折腾电脑的玩家或团队制作的,根据制作者和团队的不同,PE 的功能也会有所不同。但核心的系统安装、系统备份还原、硬盘分区、启动修复之类的系统维护功能还是有的,而且大多差别不大。 区别基本在于集成维护工具的数量,比如一个简单的系统安装功能,可以通过很多工具来实现,不同 PE 之间的区别仅在于工具数量和工具版本的新旧。 其次,一些常用的工具还有开机密码去除、硬件检测等功能,还有一个实用的功能就是文件强制删除,相信有些小伙伴在删除文件时会遇到出现权限不足等提示而无法删除,在PE中就不会出现这样的情况,因为PE是默认以最高权限运行的,对于这类情况可以直接删除。 一些功能比较丰富的 PE 还会具备联网功能,以及集成一些常用软件(如 Office),如果只是临时使用,甚至可以把它当作一个正常的系统来使用。 三、使用 PE 安装系统的好处? 首先当然是如上所述,PE 功能齐全,类似硬盘分区等操作你都可以在装系统之前提前搞定,避免了装完系统之后还要一步步去搞定的麻烦。 其次,个人觉得最方便的就是可以用最简单的方法一次性创建多系统启动盘。 用U盘装系统的朋友应该都知道,在制作启动U盘时一般一个系统只能写入一次,比如你只有一个U盘,你要装Win10就要制作一个启动盘,要装Win7又要重新制作一个,而且每次都要格式化,非常不方便。虽然也有制作一体化镜像,然后一次性写入的方法,但操作起来太麻烦、太繁琐。 有了 PE,就可以避免这种麻烦,只需把 PE 写入 U 盘,然后把需要安装的系统镜像都放到 U 盘里,只要 U 盘空间足够,想放多少就放多少,避免了因为安装不同系统而反复制作启动盘的麻烦。而且,由于制作一次后无需格式化,你还可以在 U 盘中放入其他数据,而不必担心文件丢失。 四、可靠的好 PE 推荐 其实,PE工具虽然有很多种,但其实功能都差不多,无非就是更新的快慢而已。 但关键在于靠谱,什么叫靠谱呢?虽然都能用,功能也全,但有的夹杂着 "私货"。说白了,就是捆绑软件,或者捆绑主页,或者怎么卸载都不干净的那种。
-
担心 Harbor 数据丢失?谈谈 Harbor 的备份和恢复方法。