使用 Longhorn 作为 K8s 后端储存
简单介绍
Longhorn 是一个分布式存储系统,具有以下特点:
- 使用 Longhorn 卷作为 K8s 集群的持久存储卷。
- 使用块存储设备作为基础卷,无需依赖云服务提供商。
- 通过在多个节点上存储副本来提供高可用性。
- 支持将 NFS 用作存储系统的备份源,并且可以设置多个备份源。
- 支持跨集群灾备,方便在 K8s 集群中迁移数据。
- 可以在不中断持久卷的情况下升级 Longhorn 系统。
官方参考文档:
https://longhorn.io/docs/1.2.6
中文参考文档:
https://blog.51cto.com/u_15168528/3605855
结构原理:
https://jishuin.proginn.com/p/763bfbd73e98
准备工作
在集群中每个节点安装并启动 open-iscsi :
[root@k8s-101 ~]# yum install -y nfs-utils
[root@k8s-101 ~]# yum --setopt=tsflags=noscripts install -y iscsi-initiator-utils
[root@k8s-101 ~]# /sbin/iscsi-iname -p "InitiatorName=iqn.2022-05.org.open-iscsi" > /etc/iscsi/initiatorname.iscsi
[root@k8s-101 ~]# systemctl enable --now iscsid
[root@k8s-101 ~]# lsmod | grep iscsi
scsi_transport_iscsi 110592 1
或使用官方脚本来安装:
[root@k8s-101 ~]# kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.2.6/deploy/prerequisite/longhorn-iscsi-installation.yaml
部署流程
在主节点上克隆仓库,并检出到 v1.2.6 分支:
[root@k8s-101 ~]# git clone https://github.com/longhorn/longhorn.git
[root@k8s-101 ~]# cd longhorn && git checkout v1.2.6
如果遇到错误:
fatal: unable to access ‘https://github.com/longhorn/longhorn.git/’: TCP connection reset by peer
多试几次,直到匹配上能连通的 Github 服务器 IP 地址。
运行官方环境检测脚本,一般没有报错:
[root@k8s-101 ~]# bash scripts/environment_check.sh
[INFO] All longhorn-environment-check pods are ready (6/6).
[INFO] Required packages are installed.
[INFO] MountPropagation is enabled.
[INFO] Cleaning up longhorn-environment-check pods...
[INFO] Cleanup completed.
将 deploy
目录下的 longhorn.yaml
文件拷贝出来,直接部署:
[root@k8s-101 longhorn]# mkdir -p /hxz393/local/longhorn/apply && cp deploy/longhorn.yaml /hxz393/local/longhorn/apply/
[root@k8s-101 longhorn]# kubectl apply -f /hxz393/local/longhorn/apply/
[root@k8s-101 longhorn]# kubectl get po -n longhorn-system -owide --watch
等待所有组件容器变为 Running 状态。
集群配置
配置应用使用的自定义 SC 和前端访问网址。
建立 SC
自定义 SC 配置好默认自动备份策略,涵盖了每周一次备份、每天一次备份和每三小时一次快照:
[root@k8s-101 ~]# tee /hxz393/local/longhorn/apply/kube-sc.yaml<<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: kube-sc
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: Immediate
parameters:
numberOfReplicas: "3"
staleReplicaTimeout: "2880"
fromBackup: ""
fsType: "xfs"
recurringJobSelector: '[
{
"name":"kube-snap",
"task":"snapshot",
"cron":"0 0/3 * * ?",
"retain":5
},
{
"name":"kube-backup-daily",
"task":"backup",
"cron":"0 2 * * ?",
"retain":7
},
{
"name":"kube-backup-weekly",
"task":"backup",
"cron":"0 3 ? * SAT",
"retain":4
}
]'
EOF
[root@k8s-101 ~]# kubectl apply -f /hxz393/local/longhorn/apply/kube-sc.yaml
开放端口
修改 longhorn-frontend 服务类型为 nodeport,暴露端口 10005 留作内网访问:
[root@k8s-101 ~]# kubectl -n longhorn-system edit svc longhorn-frontend
...
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
nodePort: 10005
selector:
app: longhorn-ui
sessionAffinity: None
type: NodePort
...
通过服务器 IP 地址加 10005 端口,能直接打开 Longhorn 控制面板。
配置域名
由于 Longhorn 控制面板默认不带身份验证,如果想通过域名访问,需要自行生成用户密码加密文件:
[root@k8s-101 ~]# htpasswd -m -c /hxz393/local/nginx/cert/longhorn_passwd assassing
命令 htpasswd
为 Apache httpd
服务所带套件,需要自行安装。
建立 nginx
配置文件:
[root@k8s-101 ~]# vi /hxz393/local/nginx/config/conf.d/longhorn.x2b.net.conf
server {
listen 80;
listen 443 ssl;
# 域名
server_name longhorn.x2b.net;
ssl_certificate /cert/x2b.net.pem;
ssl_certificate_key /cert/x2b.net.key;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.2 TLSv1.3 SSLv3;
ssl_prefer_server_ciphers on;
# 基本认证
auth_basic "nginx basic auth for longhorn";
auth_basic_user_file /cert/longhorn_passwd;
location / {
# k8s服务名
proxy_pass http://longhorn-frontend.longhorn-system/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
if ($request_uri ~* "/(.*)"){
proxy_pass http://longhorn-frontend.longhorn-system/$1;
break;
}
}
}
[root@k8s-101 ~]# for i in $(kubectl get pod -n local|grep nginx|awk '{print $1}');do kubectl exec -it -n local $i -- nginx -s reload; done
通过域名 longhorn.x2b.net
访问,需要输入用户名 assassing 的密码来访问。
节点配置(Node)
根据需要修改默认节点 Node 配置:
- 删除所有节点默认挂载点。
- 添加主节点
/ssd
目录作为储存目录 ,开启调度(Scheduling),设置保留磁盘(Storage Reserved)空间为 1 GB。
备份任务(Recurring Job)
创建快照策略 kube-snap,用来自动创建快照:
- Name:输入名字 kube-snap。
- Task:任务类型选择 Snapshot。
- Retain:设置保留副本数量为 5。
- Concurrency:并发活动数为 3。
- Cron:设置任务调度表为
0 0/3 * * ?
,代表每 3 小时执行一次。
创建备份策略 kube-backup-daily,用来每天自动创建备份。需要先设置好备份 NFS 服务器地址:
- Name:输入名字 kube-backup-daily。
- Task:任务类型选择 Backup。
- Retain:设置保留副本数量为 7。
- Concurrency:并发活动数为 1。
- Cron:设置任务调度表为
0 2 * * ?
,代表每天的凌晨 2 点执行。
创建备份策略 kube-backup-weekly,用来每周自动创建备份:
- Name:输入名字 kube-backup-weekly。
- Task:任务类型选择 Backup。
- Retain:设置保留副本数量为 4。
- Concurrency:并发活动数为 1。
- Cron:设置任务调度表为
0 6 ? * SAT
,代表每周六早上 6 点执行。
功能设置(Setting)
遵循最小化配置原则,一般不建议修改默认配置。修改前请一定先查询官方文档。
Orphan
-
Orphan Auto-Deletion
自动删除孤儿容器。
Backup
-
Backup Target
填写备份 NFS 服务器地址。例如:
nfs://192.168.1.106:/backup
。
Scheduling
-
Replica Node Level Soft Anti-Affinity
开启节点级别反亲和策略。同节点部署多个相同的副本没有意义。
-
Storage Over Provisioning Percentage
设置超量调度百分比为 100%。
本地挂载
可以将活动中的储存卷挂载到本地,来管理卷内文件:
- 在卷的详细信息(Volume Details)中找到
Attached Node & Endpoint
,这是 PVC 挂载到的目标服务器和设备名。 - 登录目标服务器,使用
mount
命令来挂载RWX
卷。例如:mount /dev/longhorn/pvc-9a38209a-ca92-44b3-adba-e1c629437409 /root/temp_pvc
。 - 维护完毕用
umount
卸载卷:umount /root/temp_pvc
。
磁盘瘦身
针对 RWO
格式的卷,1.40 以上版本提供清理磁盘空间功能,在卷操作中选择 Trim Filesystem
即可。
对于 RWX
卷需要手动清理。例如:
[root@k8s-101 ~]# mkdir 111 && mount /dev/longhorn/pvc-41795a8f-d3bf-406b-acfd-fa7d88e44e73 111
[root@k8s-101 ~]# fstrim 111
[root@k8s-101 ~]# umount 111 && rmdir 111
版本升级
目前最新版为 1.4.2,根据官方文档说明,从 1.2.X 升级需要先升级到 1.3.3 版本,再升级到 1.4.2。升级时访问控制台会中断一会,但不影响储存卷工作。
依然可以用安装时克隆的仓库来操作。或则删除后重新克隆仓库:
[root@k8s-101 ~]# cd longhorn && git checkout v1.3.3
Previous HEAD position was f936f6e... Release 1.2.6
HEAD is now at f57838c... release: 1.3.3
后续步骤和安装一样:
[root@k8s-101 longhorn]# cp deploy/longhorn.yaml /hxz393/local/longhorn/apply/
[root@k8s-101 longhorn]# kubectl apply -f /hxz393/local/longhorn/apply/
[root@k8s-101 longhorn]# kubectl get po -n longhorn-system -owide --watch
如果网络不错,可以直接指定 Github 上的发布文件来升级:
[root@k8s-101 longhorn]# kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.4.2/deploy/longhorn.yaml
升级后需要重新修改前端服务类型:
[root@k8s-101 ~]# kubectl -n longhorn-system edit svc longhorn-frontend
数据恢复
通过控制面板正常恢复卷备份操作不在本段讨论之列。这里要假设的是一个极端的情况:整个 K8s 集群或者 Longhorn 系统失败且无法恢复,要怎么取出 Longhrn 卷的数据。
由于 Longhorn 在磁盘中,以 img 格式来封装数据:
[root@k8s-250 ~]# ll /ssd/replicas/pvc-10efcd2b-df0d-4af3-b9cc-3b61368bbdb2-8d14ac1d/
total 1312920
-rw------- 1 root root 4096 May 21 21:28 revision.counter
-rw-r--r-- 1 root root 5368709120 May 21 21:28 volume-head-007.img
-rw-r--r-- 1 root root 187 May 21 08:00 volume-head-007.img.meta
-rw-r--r-- 1 root root 203 May 21 08:00 volume.meta
-rw-r--r-- 1 root root 5368709120 May 21 08:00 volume-snap-kube-bac-3fe04efe-14ed-4dc9-a3d6-e938e20bb8e3.img
-rw-r--r-- 1 root root 193 May 21 08:00 volume-snap-kube-bac-3fe04efe-14ed-4dc9-a3d6-e938e20bb8e3.img.meta
-rw-r--r-- 1 root root 5368709120 May 21 08:00 volume-snap-kube-sna-427d25c2-4eea-4e6a-a6c0-791e931451ef.img
-rw-r--r-- 1 root root 210 May 21 08:00 volume-snap-kube-sna-427d25c2-4eea-4e6a-a6c0-791e931451ef.img.meta
所以即使找到了 PV 所在目录也无法直接操作。先查看卷目录下的 volume.meta
文件内容:
[root@k8s-250 ~]# cat /ssd/replicas/pvc-10efcd2b-df0d-4af3-b9cc-3b61368bbdb2-8d14ac1d/volume.meta
{"Size":5368709120,"Head":"volume-head-007.img","Dirty":true,"Rebuilding":false,"Error":"","Parent":"volume-snap-kube-sna-427d25c2-4eea-4e6a-a6c0-791e931451ef.img","SectorSize":512,"BackingFilePath":""}
通过文件内容,无法得知卷的用途。只知道卷的大小为 5368709120 Bytes(5 GB)。
接着使用 longhorn-engine
镜像手动创建卷容器,命令参数为:docker run -v /dev:/host/dev -v /proc:/host/proc -v 卷实际路径:/volume --privileged longhornio/longhorn-engine:v1.4.1 launch-simple-longhorn 卷名 卷大小
。
在上面例子中,卷路径是 /ssd/replicas/pvc-10efcd2b-df0d-4af3-b9cc-3b61368bbdb2-8d14ac1d/
,卷大小为 5368709120
。而卷名,也就是 PV 名字 pvc-10efcd2b-df0d-4af3-b9cc-3b61368bbdb2
在路径名中也有体现,统一去掉最后一段 8 位长度 UUID 名 8d14ac1d
即可,PV 名字长度是固定的 40 位。
所以实际要运行的命令是:
[root@k8s-250 ~]# docker run -v /dev:/host/dev -v /proc:/host/proc -v /ssd/replicas/pvc-10efcd2b-df0d-4af3-b9cc-3b61368bbdb2-8d14ac1d:/volume --privileged longhornio/longhorn-engine:v1.4.1 launch-simple-longhorn pvc-10efcd2b-df0d-4af3-b9cc-3b61368bbdb2 5368709120
如果运行顺利,可以通过 mount
命令来挂载块设备 /dev/longhorn/卷名
。挂载步骤参考:本地挂载