侧边栏壁纸
博主头像
Blog博主等级

行动起来,活在当下

  • 累计撰写 211 篇文章
  • 累计创建 94 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

k3s持久化存储--NFS

一、基础环境

  • master:

192.168.1.189

  • node1:

192.168.1.190

  • node2:

192.168.1.188

二、NFS服务端部署

本文选择 IP 为 192.168.1.188 的 node2 节点,作为 NFS 存储服务器。

安装 NFS 服务端软件包并创建共享目录

yum install nfs-utils -y 
mkdir -p /home/data/k8s
chown nfsnobody:nfsnobody /home/data/k8s

编辑服务配置文件

配置 NFS 服务器数据导出目录及访问 NFS 服务器的客户端机器权限。

编辑配置文件 vi /etc/exports,添加如下内容

/home/data/k8s 192.168.1.0/24(rw,sync,all_squash,anonuid=65534,anongid=65534,no_subtree_check)

说明:

192.168.1.0/24:可以访问 NFS 存储的客户端 IP 地址

rw:读写操作,客户端机器拥有对卷的读写权限。

sync:内存数据实时写入磁盘,性能会有所限制

all_squash:NFS 客户端上的所有用户在使用共享目录时都会被转换为一个普通用户的权限

anonuid:转换后的用户权限 ID,对应的操作系统的 nfsnobody 用户 anongid:转换后的组权限 ID,对应的操作系统的 nfsnobody 组 no_subtree_check:不检查客户端请求的子目录是否在共享目录的子树范围内,也就是说即使输出目录是一个子目录,NFS 服务器也不检查其父目录的权限,这样可以提高效率。

启动服务并设置开机自启

systemctl enable nfs-server --now

查看共享目录

查看导出目录

[root@k3s-node2 ~]# exportfs -v 
/home/data/k8s	192.168.1.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,root_squash,all_squash)

客户端挂载测试

找一台额外的机器作为客户端验证测试,本示例使用 node1节点。

  • 创建测试挂载点

mkdir -p /home/nfs-node2/
  • 安装 NFS 软件包(一定要安装,否则无法识别 nfs 类型的存储)

yum install nfs-utils
  • 挂载 NFS 共享目录

mount -t nfs 192.168.1.188:/home/data/k8s /home/nfs-node2
  • 增删改查测试

# 创建测试目录、创建测试文件、测试文件写入内容、查看写入目录和文件权限、删除目录和文件
[root@k8s-master-1 ~]# cd /home/nfs-node2
[root@k3s-node1 nfs-node2]# mkdir nfs-test
[root@k3s-node1 nfs-node2]# touch nfs-test.txt
[root@k3s-node1 nfs-node2]# echo "nfs-test" > nfs-test.txt
[root@k3s-node1 nfs-node2]# ll
total 4
drwxr-xr-x 2 nfsnobody nfsnobody 6 Nov 29 16:56 nfs-test
-rw-r--r-- 1 nfsnobody nfsnobody 9 Nov 29 16:56 nfs-test.txt
[root@k3s-node1 nfs-node2]# rmdir nfs-test
[root@k3s-node1 nfs-node2]# rm nfs-test.txt
rm: remove regular file ‘nfs-test.txt’? y
[root@k3s-node1 nfs-node2]# ll
total 0

检查 nfs 服务器端是否有设置共享目录

[root@k3s-node1 nfs-node2]# showmount  -e 192.168.1.188 
Export list for 192.168.1.188:
/home/data/k8s 192.168.1.0/24

其他命令

卸载挂载

df -hT 
192.168.1.188:/home/data/k8s nfs4       46G   32M   46G   1% /home/nfs-node2

umount /home/nfs-node2

查看nfs版本

# 查看nfs服务端信息(服务端执行)
nfsstat -s
# 查看nfs客户端信息(客户端执行)

nfsstat -c

三、安装 Kubernetes NFS Subdir External Provisioner

想要 Kubernetes 支持 NFS 存储,我们需要安装 nfs-subdir-external-provisioner ,它是一个存储资源自动调配器,它可将现有的 NFS 服务器通过持久卷声明来支持 Kubernetes 持久卷的动态分配。该组件是对 Kubernetes NFS-Client Provisioner 的扩展, nfs-client-provisioner 已经不提供更新,而且 Github 仓库 也已经处于归档状态,已经迁移到 nfs-subdir-external-provisioner 的仓库。

官方提供的安装方式有三种:

使用 Helm 的方式比较简单,也是现在官方推荐的、使用率最高的方式,本文仅实战演示 Helm 部署方式,其他方式请参考官方文档。

集群节点安装 NFS Client

所有 Kubernetes 集群节点需要提前安装 nfs-utils,否则在部署过程中会报错。

yum install nfs-utils

添加 Helm 源

helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner

创建 NameSpace

可选配置,主要是方便资源管理

kubectl create ns nfs-system

命令行快速安装 Kubernetes NFS Subdir External Provisioner

(首选方案,使用命令行设置变量参数)

helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --set storageClass.name=nfs-sc --set nfs.server=192.168.9.81 --set nfs.path=/data/k8s -n nfs-system

说明:

--set storageClass.name=nfs-sc:指定 storageClass 的名字

--set nfs.server=192.168.9.81:指定 NFS 服务器的地址

--set nfs.path=/data/k8s:指定 NFS 导出的共享数据目录

--set storageClass.defaultClass=true:指定为默认的 sc,本示例没使用

-n nfs-system:指定命名空间。

这条命令创建了一个名称为nfs-subdir-external-provisioner 的deploy,通过deploy 生成一个名字nfs-subdir-external-provisioner开头的pod。

这里如果有如下报错:

Error: INSTALLATION FAILED: Kubernetes cluster unreachable: Get "http://localhost:8080/version": dial tcp [::1]:8080: connect: connection refused

报错原因: helm v3版本不再需要Tiller,而是直接访问ApiServer来与k8s交互,通过环境变量KUBECONFIG来读取存有ApiServre的地址与token的配置文件地址,默认地址为~/.kube/config

解决方式:

vi /etc/profile
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
source /etc/profile

再次执行install命令即可。

查看pod状态,如果发现ImagePullBackOff

kubectl describe po nfs-subdir-external-provisioner-79dbb5748c-g96m7 -n nfs-system

nfs-system     nfs-subdir-external-provisioner-79dbb5748c-g96m7   0/1     ImagePullBackOff   0             4m30s

将deploy中镜像地址改为国内地址:

kubectl edit  deploy nfs-subdir-external-provisioner  -n nfs-system
国内地址:
k8s.mirror.nju.edu.cn/sig-storage/nfs-subdir-external-provisioner:v4.0.2

更改后通过deploy方式创建的pod会自动重新部署。

最后查看pod 及deploy 对应状态都running 即可。

[root@k3s-master helm]# kubectl get deploy -n nfs-system
NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
nfs-subdir-external-provisioner   1/1     1            1           22m
[root@k3s-master helm]# kubectl get po  -n nfs-system
NAME                                               READY   STATUS    RESTARTS   AGE
nfs-subdir-external-provisioner-7d4cf6df47-jkv8j   1/1     Running   0          8m15s
[root@k3s-master helm]# 

验证测试

查看创建的资源

  • 查看 sc

[root@k3s-master ~]# kubectl get sc nfs-sc -o wide
NAME     PROVISIONER                                     RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-sc   cluster.local/nfs-subdir-external-provisioner   Delete          Immediate           true                   66s
  • 查看 Deployment

[root@k3s-master ~]# kubectl get deployment -n nfs-system -o wide
NAME                              READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS                        IMAGES                                                               SELECTOR
nfs-subdir-external-provisioner   1/1     1            1           73m   nfs-subdir-external-provisioner   registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2   app=nfs-subdir-external-provisioner,release=nfs-subdir-external-provisioner
  • 查看 Pod

[root@k3s-master ~]# kubectl get pod -n nfs-system -o wide
NAME                                               READY   STATUS    RESTARTS   AGE     IP            NODE           NOMINATED NODE   READINESS GATES
nfs-subdir-external-provisioner-65f66bc6cd-hdpts   1/1     Running   0          4m20s   10.233.85.5   k8s-master-2   <none>           <none>

以下测试根据《kubernetes修炼手册》10.2 StatefulSet实战中例子稍加修改。

部署headless svc

headless-svc.yml

# Headless Service for StatefulSet Pod DNS names
apiVersion: v1
kind: Service
metadata:
  name: dullahan
  labels:
    app: web
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: web

部署sts

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: tkb-sts
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  serviceName: "dullahan"
  template:
    metadata:
      labels:
        app: web
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: ctr-web
        image: nginx:latest
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: webroot
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: webroot
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "nfs-sc"
      resources:
        requests:
          storage: 1Gi

部署sts的前提是必须先部署svc 和sc 。

sc 我使用本地刚刚创建的nfs-provisioner 名称为:nfs-sc

应用上述配置:

[root@k3s-master sts]# kubectl apply -f headless-svc.yml -n nfs-system
[root@k3s-master sts]# kubectl apply -f sts.yml -n nfs-system

查看部署情况:

[root@k3s-master sts]# kubectl get sts -n nfs-system 
NAME      READY   AGE
tkb-sts   3/3     118m
[root@k3s-master sts]# kubectl get svc -n nfs-system 
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
dullahan   ClusterIP   None         <none>        80/TCP    119m

查看sts配置文件中volumeClaimTemplate字段,它用于在每次创建一个新的Pod副本的时候,自动创建一个PVC。和sc绑定实现动态pvc。

  volumeClaimTemplates:
  - metadata:
      name: webroot
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "nfs-sc"
      resources:
        requests:
          storage: 1Gi

进入node2 nfs服务器端共享数据目录内可以发现,卷的命名方式为:

命名空间(ns)名称+ pvc名称 + pv名称

[root@k3s-node2 k8s]# cd /home/data/k8s/
[root@k3s-node2 k8s]# ll
total 0
drwxrwxrwx. 2 nfsnobody nfsnobody 6 Jun  2 02:52 nfs-system-webroot-tkb-sts-0-pvc-99b2d103-00ff-488b-8486-a0ee6c1bc03f
drwxrwxrwx. 2 nfsnobody nfsnobody 6 Jun  2 02:52 nfs-system-webroot-tkb-sts-1-pvc-09433273-90ef-4755-b01b-59279888839f
drwxrwxrwx. 2 nfsnobody nfsnobody 6 Jun  2 02:53 nfs-system-webroot-tkb-sts-2-pvc-f022bacc-e6c2-4bb4-a839-95e5009f145c

一个重要的结论,只要不删除pvc ,数据永远不会随着sts扩缩容消失。sts扩缩容还会使用原先绑定的pvc。

如果删除pvc ,那么对应的卷名称会更改为:

archived + pvc名称 + pv 

再次生成相同名称的pvc也不会和原先的卷绑定,因为pv 名称是哈希值,哈希值会改变。

关于域名的测试,可以按照《kuberbetes 修炼手册》 10.2.4 中创建带有测试工具的pod

jump-pod.yml

apiVersion: v1
kind: Pod
metadata:
  name: jump-pod
spec:
  terminationGracePeriodSeconds: 1
  containers:
  - image: k8s.mirror.nju.edu.cn/e2e-test-images/jessie-dnsutils:1.7
    name: jump-ctr
    tty: true
    stdin: true

应用pod

$ kubectl apply -f jump-Pod.yml -n nfs-system

进入测试Pod执行命令。

$ kubectl exec -it jump-Pod -n nfs-system  -- bash 
root@jump-Pod:/# 

测试:

root@jump-pod:/# dig dullahan.nfs-system.svc.cluster.local 

; <<>> DiG 9.9.5-9+deb8u19-Debian <<>> dullahan.nfs-system.svc.cluster.local
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5519
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;dullahan.nfs-system.svc.cluster.local. IN A

;; ANSWER SECTION:
dullahan.nfs-system.svc.cluster.local. 5 IN A	10.42.2.104
dullahan.nfs-system.svc.cluster.local. 5 IN A	10.42.0.84
dullahan.nfs-system.svc.cluster.local. 5 IN A	10.42.1.92

;; Query time: 1 msec
;; SERVER: 10.43.0.10#53(10.43.0.10)
;; WHEN: Sun Jun 02 09:04:44 UTC 2024
;; MSG SIZE  rcvd: 225

该查询命令返回了每个Pod的DNS全限定名和IP。其他应用,当然也包括该应用自身, 都可以使用这种方式来查找StatefulSet的所有Pod。 当然,这种方法能够奏效的前提是,应用必须知道StatefulSet的governing Service的名 字,而且StatefulSet 的Pod 必须匹配该governing Service 的 Label 筛选器。

四、helm 的安装

只需要在master节点上安装即可

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod +x get_helm.sh
./get_helm.sh

查看是否安装成功

[root@k3s-master ~]# helm version 
version.BuildInfo{Version:"v3.15.1", GitCommit:"e211f2aa62992bd72586b395de50979e31231829", GitTreeState:"clean", GoVersion:"go1.22.3"}

相关参考:

https://cloud.tencent.com/developer/article/2365976

https://developer.aliyun.com/article/856853

0

评论区