- 作者:老汪软件技巧
- 发表时间: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中使用其他存储技术的应用实例,帮助您找到最适合自己业务需求的存储方案。感谢您的阅读,期待我们在下一篇文章中继续探索更为先进和高效的技术。