• 作者:老汪软件技巧
  • 发表时间:2024-08-20 04:01
  • 浏览量:

背景

在容器化应用的大潮中,Kubernetes凭借其强大的调度和管理能力,已经成为企业部署和管理容器的重要工具。然而,随着应用的不断复杂化和数据量的激增,如何在Kubernetes环境中实现高效、灵活的持久化存储,成为了架构师和运维工程师们关注的焦点问题。NFS(Network File System),作为一种成熟且广泛应用的网络文件系统,为Kubernetes提供了一种便捷的存储解决方案。

概要

本篇文章将详细介绍如何在Kubernetes中配置和使用NFS作为存储插件。我们将从NFS服务器的安装与配置开始,逐步演示如何在Kubernetes集群中使用NFS实现持久化存储。通过具体的实例,如部署Nexus3,我们将探讨如何将NFS集成到实际的容器化应用中。同时,我们还将介绍如何通过Helm部署NFS Subdir External Provisioner,实现自动化的存储管理。无论您是Kubernetes的新手还是有经验的运维人员,这篇文章都将为您提供实用的指导和最佳实践。

安装 NFS 服务器

作者把该服务器安装在 master 节点。

通过 ssh 连接上我们的 k8s-master

ssh root@192.168.32.32

安装 NFS 内核服务

首先,我们将在 Ubuntu 上安装 NFS 内核服务器包,这实际上会将其变成 NFS 服务器。但首先,让我们更新软件包列表,如图所示。

sudo apt update

之后,运行以下命令来安装 NFS 内核服务器包。

sudo apt install nfs-kernel-server

您可以验证 nfs-server 服务是否正在运行,如图所示

sudo systemctl status nfs-server

创建 NFS 共享目录

创建 /mnt/nfs 文件目录,用于共享

sudo mkdir -p /mnt/nfs

由于我们希望所有客户端都可以访问所有文件,因此我们将分配以下目录所有权和权限。

sudo chown nobody:nogroup /mnt/nfs
sudo chmod -R 777 /mnt/nfs

这些权限是递归的,将应用于您将创建的所有文件和子目录。

设置访问权限

创建 NFS 目录共享并分配所需的权限和所有权后,我们需要允许客户端系统访问 NFS 服务器。我们将通过编辑在安装 nfs-kernel-server 软件包期间创建的 /etc/exports 文件来实现这一点。

因此,打开 /etc/exports 文件。

sudo vim /etc/exports

设置运行访问的 IP 范围, * 表示允许任意 ip 访问。

/mnt/nfs 192.168.32.0/24(rw,sync,no_root_squash,no_subtree_check)

导出共享目录

要导出目录并使其可用,请调用以下命令:

sudo exportfs -a

为了确定导出列表,您可以使用以下命令显示导出列表:

sudo exportfs -s
# /mnt/nfs  192.168.32.0/24(rw,wdelay,no_root_squash,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)

配置防火墙规则

如果您位于 UFW 防火墙后面,则需要使用所示语法允许 NFS 流量通过防火墙。

查看防火墙状态

sudo ufw status
# Status: inactive

提示防火墙未激活,很好,否则,我们需要添加如下规则

_打造高效课堂_高效激励-打造常青企业

sudo ufw allow from 192.168.32.0/24 to any port nfs

安装 NFS 客户端

为了让所有的 Worker 节点都可以使用 NFS 服务器,我们需要在每个 Worker 节点上安装 NFS 客户端。

现在登录到 Worker 节点更新包索引并安装 nfs-common

sudo apt update
sudo apt install nfs-common

到目前为止,就可以手动使用基于 NFS 的 PV 对象了。

使用示例:部署nexus3

这里有几个需要注意的点,我们需要以使用非 root 用户运行容器:

we were specify a different UID and GID in the Pod's securityContext to run the container with a non-root user. For example:

    spec:
      volumes:
        - name: data-nexus
          nfs:
            server: 10.32.224.99
            path: /mnt/nfs/nexus-sit/
      containers:
        - name: nexus3-sit
          volumeMounts:
            - name: data-nexus
              mountPath: /nexus-data        
      securityContext:
        runAsUser: 1000
        runAsGroup: 1000

所以需要给 NFS server 进行授权

Ensure that the files or directories on the NFS server that you want the Kubernetes Pod to access are owned by UID 1000 and GID 1000. You can use the chown command on the NFS server to set ownership:

sudo chown -R 1000:1000  /mnt/nfs

完整的编排文件如下:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nexus3-sit
  namespace: nexus-system
  labels:
    dce.daocloud.io/app: nexus3-sit
  annotations:
spec:
  replicas: 1
  selector:
    matchLabels:
      dce.daocloud.io/component: nexus3-sit
  template:
    metadata:
      name: nexus3-sit
      creationTimestamp: null
      labels:
        dce.daocloud.io/app: nexus3-sit
        dce.daocloud.io/component: nexus3-sit
    spec:
      volumes:
        - name: data-nexus
          nfs:
            server: 10.32.224.99
            path: /mnt/nfs/nexus-sit/
      initContainers:
        - name: init-nexus3
          image: busybox
          command:
            - sh
            - '-c'
            - ulimit -n 65536
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: Always
          securityContext:
            privileged: true
            runAsUser: 0
      containers:
        - name: nexus3-sit
          image: bootstrap.ms-ctl.aswatson.net/sonatype/nexus3:3.70.0
          env:
            - name: INSTALL4J_ADD_VM_PARAMS
              value: |-
                -Xms2703M -Xmx2703M
                -XX:MaxDirectMemorySize=2703M
                -XX:+UnlockExperimentalVMOptions
                -XX:+UseCGroupMemoryLimitForHeap
                -Djava.util.prefs.userRoot=/nexus-data/javaprefs
          resources:
            limits:
              cpu: '4'
              memory: 4Gi
            requests:
              cpu: '2'
              memory: 4Gi
          volumeMounts:
            - name: data-nexus
              mountPath: /nexus-data
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 60
      dnsPolicy: ClusterFirstWithHostNet
      securityContext:
        runAsUser: 1000
        runAsGroup: 1000
      schedulerName: default-scheduler
      dnsConfig: {}
  strategy:
    type: Recreate
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

安装 NFS Subdir External Provisioner

NFS Subdir External Provisioner 是一个 Kubernetes 的动态存储卷插件,它可以在 NFS 服务器上自动创建 PV 对象。

作者使用 Helm 来安装 NFS Subdir External Provisioner。

添加 Helm 仓库

添加 NFS Subdir External Provisioner 到 Helm Chart

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

生成配置文件

获取默认的 values 配置文件

helm show values nfs-subdir-external-provisioner/nfs-subdir-external-provisioner > values.yaml

修改 values.yaml 文件,配置 NFS 服务器 IP 地址和共享目录

nfs:
  server: nfs.todoit.tech
  path: /mnt/nfs
  mountOptions:
  volumeName: nfs-subdir-external-provisioner-root
  # Reclaim policy for the main nfs volume
  reclaimPolicy: Retain

部署

运行如下命令,可以看到最终生成的部署文件

helm install -f values.yaml nfs nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --dry-run

如果没有问题,则运行如下命令进行正式部署

# 先创建名称空间
kubectl create ns nfs-provisioner
​
helm install -f values.yaml nfs nfs-subdir-external-provisioner/nfs-subdir-external-provisioner -n nfs-provisioner

等待部署成功

kubectl get pods -n nfs-provisioner -w
# NAME                                                   READY   STATUS              RESTARTS   AGE
# nfs-nfs-subdir-external-provisioner-74d67dc47b-ttgdj   0/1     ContainerCreating   0          4s
# nfs-nfs-subdir-external-provisioner-74d67dc47b-ttgdj   1/1     Running             0          36s

默认情况下,NFS Subdir External Provisioner 会创建一个名为 nfs-client 的 StorageClass,可以通过如下命令查看

kubectl get sc
# NAME         PROVISIONER                                         RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
# nfs-client   cluster.local/nfs-nfs-subdir-external-provisioner   Delete          Immediate           true                   53s

结束语

虽然NFS在Kubernetes环境中提供了一种简单易用的存储方案,但它并非完美的选择。在处理大型分布式系统、高并发场景或需要更高数据安全性的情况下,NFS的性能和稳定性可能会受到限制。因此,对于生产环境或关键任务应用,您可能需要考虑更强大的存储解决方案,如Ceph、GlusterFS或其他分布式文件系统。

未来,我计划分享更多关于在Kubernetes中使用其他存储技术的应用实例,帮助您找到最适合自己业务需求的存储方案。感谢您的阅读,期待我们在下一篇文章中继续探索更为先进和高效的技术。