raspberry pi
临时容器很有用,但有时数据需要在容器之间保留或在多个容器之间共享。 解决方案是在容器内部安装外部卷,这是在具有持久卷的Kubernetes中完成的。 在大型公共云部署中,Kubernetes与云提供商的块存储后端集成在一起,从而使开发人员可以为要用于其部署的卷创建声明,而Kubernetes与云提供商合作可以创建卷并将其安装在开发人员中豆荚。
您可以使用Kubernetes Incubator外部存储项目中的网络文件系统(NFS)-客户端供应器在“家中的私有云” Kubernetes群集中复制相同的行为。
(克里斯·柯林斯(Chris Collins), CC BY-SA 4.0 )
在上一篇文章中,我解释了如何使用Raspberry Pi设置NFS服务器 。 您可以使用此NFS服务器备份NFS客户端预配器提供的存储。 设置程序运行一个容器,该容器从您的NFS服务器装载NFS导出,并在创建持久卷声明时将其雕刻为“卷”,从而请求Pod的卷。 Kubernetes原生支持NFS卷类型,并在Pod启动时处理将卷安装在容器内的情况。
持久卷,持久卷声明和存储类
永久卷是由非临时存储支持的卷,这些卷可以作为卷安装在容器内。 写入该卷的数据在容器重新启动后仍然存在,并且可以在替换旧容器时将其装入新容器中。 对于NFS卷,可以将这些卷同时安装到多个容器中,从而可以共享数据。
开发人员可以向Kubernetes请求具有永久卷声明 (PVC)的永久卷 。 这就是听起来的样子:对符合某些条件(例如访问模式或大小)的卷的请求,该卷可以声明并用于项目。 持久卷使用存储类请求特定的卷类型。
存储类描述了可以声明的卷的类型,从而使开发人员可以选择最能满足其需求的卷类型。 管理员可以创建多种类型的存储类别以满足特定需求,例如访问模式或大小(如上所述),甚至速度/ IOPS类别或不同的后端技术。 存储类还可以指定负责创建和管理卷的特定供应商或软件。
集群管理员可以维护手动创建的大量预配置卷,以满足存储类的需求,但是这需要动手工作,并且扩展性不佳。 使用动态卷预配器,软件可以在创建新声明时按需处理卷的创建。 默认情况下,NFS客户端预配器具有单个存储类,并且从该存储类请求卷的PVC由预配器实现。
NFS客户端预配器
NFS客户端供应商是Kubernetes孵化器项目的一部分。 在Kubernetes集群中,该资源调配程序在一个容器中运行,该容器从现有 NFS服务器装载NFS导出-它本身不运行NFS服务器。 使用该容器,它侦听与其存储类匹配的PVC,在NFS导出中创建目录,并将每个目录作为持久卷报告给Kubernetes。 然后,Kubernetes可以将卷安装到使用该PVC中的卷的容器中。
如项目的README中所述,可以使用Helm图表来完成NFS-client Provisioning的安装,但出于教育的原因,并且由于本教程涉及在Raspberry Pis上运行Kubernetes集群并且需要进行一些调整,因此您将进行安装手动在家庭私有云群集上。
先决条件
使用NFS客户端预配器之前,必须满足两个先决条件:
- 查找NFS服务器的详细信息(IP地址和导出路径)
- 在可能运行需要NFS卷的Pod的每个Kubernetes节点上安装NFS库
如果您安装了自己的NFS服务器,例如将Raspberry Pi homelab变成网络文件系统中的服务器,则您应该已经知道服务器的IP地址和其导出文件系统的路径。 确保导出列表包含所有可能会运行带有NFS卷的Pod的Kubernetes节点。
您还需要在每个这些节点上安装NFS库,以便它们能够挂载NFS卷。 在Ubuntu,Raspbian或其他基于Debian的操作系统上,可以使用apt安装nfs-common软件包。 对于基于Red Hat的发行版,请安装nfs-utils软件包。
有了先决条件,您就可以继续将NFS客户端供应程序安装到Kubernetes集群上。
安装
使用标准的Kubernetes对象部署NFS客户端配置程序。 您可以在nfs-client目录下的Kubernetes Incubator外部存储项目中找到它们。 首先,请克隆https://github.com/kubernetes-incubator/external-storage存储库:
# Clone the external-storage repo
# (output omitted)
$
git clone https:
// github.com
/ kubernetes-incubator
/ external-storage.git
在nfs-client/deploy安装NFS-client Provisioner所需的特定部分:
$
cd external-storage
/ nfs-client
/ deploy
$
ls
class.yaml deployment.yaml rbac.yaml test-pod.yaml
deployment-arm.yaml objects test-claim.yaml
请注意, objects目录包含其父目录中的所有内容,只是分解为每个对象一个文件。
在执行其他任何操作之前,必须创建适当的基于角色的访问控制(RBAC)权限,以允许NFS客户端kubectl create服务帐户安装卷,创建PVC等。可以使用kubectl create命令在集群上kubectl create 。
如果计划在默认名称空间之外的其他名称空间中部署配置程序,请确保首先更改RBAC和部署文件中的名称空间:
# Create the RBAC permissions needed by the provisioner
kubectl create
-f rbac.yaml
serviceaccount
/ nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io
/ nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io
/ run-nfs-client-provisioner created
role.rbac.authorization.k8s.io
/ leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io
/ leader-locking-nfs-client-provisioner created
接下来,为NFS客户端供应器窗格创建部署。 如果您按照Raspberry Pi指示构建 kubernetes集群来创建Kubernetes集群,或者在基于ARM的系统上创建了自己的Kubernetes集群 ,则需要使用deployment-arm.yaml文件进行修改和部署。 如果您使用的是基于x86_64的系统,请使用deployment.yaml文件。
使用您选择的编辑器编辑文件。 您需要更改四件事。 首先,从.spec.template.containers.env列表中设置三个环境变量:
- 将PROVISIONER_NAME的值更改为nfs-storage (可选;这会使它更人性化)。
- 将NFS_SERVER值更改为NFS服务器的IP地址。
- 将NFS_PATH值更改为NFS导出的路径。
最后,在.spec.template.spec.volumes.nfs下,将server和path值更改为分别为NFS_SERVER和NFS_PATH设置的值。
例如,在NFS服务器和192.168.2.123:/srv导出路径中, deployment-arm.yaml文件将如下所示:
apiVersion
: apps/v1
kind
: Deployment
metadata :
name
: nfs-client-provisioner
labels :
app
: nfs-client-provisioner
namespace
: default
spec :
replicas
: 1
strategy :
type
: Recreate
selector :
matchLabels :
app
: nfs-client-provisioner
template :
metadata :
labels :
app
: nfs-client-provisioner
spec :
serviceAccountName
: nfs-client-provisioner
containers :
- name
: nfs-client-provisioner
image
: quay.io/external_storage/nfs-client-provisioner-arm:latest
volumeMounts :
- name
: nfs-client-root
mountPath
: /persistentvolumes
env :
- name
: PROVISIONER_NAME
value
: nfs-storage
- name
: NFS_SERVER
value
: 192.168.2.123
- name
: NFS_PATH
value
: /srv
volumes :
- name
: nfs-client-root
nfs :
server
: 192.168.2.123
path
: /srv
修改deployment-arm.yaml文件后,请使用kubectl create命令创建部署:
# Create the deployment
$ kubectl create
-f deployment-arm.yaml
deployment.apps
/ nfs-client-provisioner created
# Check that the deployment created the provisioner pod correctly
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-6ddfb9bb6d-x4zwt
1
/
1 Running
0 54s
如果一切正常,则NFS客户端配置程序现在正在集群中运行。 如果pod的状态为ContainerCreating ,并且最终不会更改为Running ,请使用kubectl get events命令检查任何相关事件。 确保用户“ nobody”对NFS服务器上的导出目录具有写权限。 如果没有问题,请继续创建存储类。
需要修改class.yaml文件,以将provisioner值设置为nfs-storage或您在deployment-arm.yaml为PROVISIONER_NAME值设置的任何值。 这告诉Kubernetes需要使用哪个供应商来实现此存储类的PVC。 假设您选择nfs-storage ,则class.yaml文件应如下所示:
apiVersion
: storage.k8s.io/v1
kind
: StorageClass
metadata :
name
: managed-nfs-storage
provisioner
: nfs-storage
# or choose another name, must match deployment's env PROVISIONER_NAME'
parameters :
archiveOnDelete
:
"false"
使用kubectl create命令创建存储类:
# Create the storage class
$ kubectl create
-f class.yaml
storageclass.storage.k8s.io
/ managed-nfs-storage created
# Verify the storage class was created
$ kubectl get storageClass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
managed-nfs-storage nfs-storage Delete Immediate
false
成功! NFS客户端供应器现已安装在Kubernetes集群中,并准备为Pod动态分配持久性存储卷,以响应针对managed-nfs-storage存储类的持久性卷声明。
测试您的新卷配置程序
安装并配置了配置程序后,您可以通过创建请求持久性卷的PVC和用于安装该卷的Pod进行测试。 幸运的是,测试对象随用于部署的文件一起提供: test-claim.yaml和test-pod.yaml 。
在创建PVC和吊舱之前,请先看一下已有的内容。 除非您已经创建了一些卷,否则不应有任何持久卷或PVC:
# Look for existing persistent volumes
$ kubectl get persistentvolumes
No resources found
in default namespace.
# Look for existing persistent volume claims
$ kubectl get persistentvolumeclaims
No resources found
in default namespace.
现在,从test-claim.yaml文件创建一个新的PVC:
# Create a test PVC
$ kubectl create
-f test-claim.yaml
persistentvolumeclaim
/ test-claim created
$ kubectl get persistentvolumeclaims
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-claim Bound pvc-bdf41489-abe4-
4508 -8adc-74e80f70c626 1Mi RWX managed-nfs-storage 7s
从上面的输出中,您可以看到一个名为test-claim的PVC已创建并绑定。 该声明与NFS客户端pvc-bdf41489-abe4-4508-8adc-74e80f70c626自动创建的名为pvc-bdf41489-abe4-4508-8adc-74e80f70c626的卷有关。 另外,请注意, STORAGECLASS被称为managed-nfs-storage ,即您创建的存储类的名称。
不用担心“ CAPACITY值。 NFS客户端预配器无法强制执行存储配额。 NFS没有该功能。 1Mi是一个占位符。
现在,PVC及其相关的持久卷已由NFS客户端供应商创建,登录到NFS服务器并查看发生了什么事:
# From the NFS host, with the directory used for the NFS export
$
ls
-la
total
4
drwxr-xr-x
3 nobody root
73 May
25
18 :
46 .
drwxr-xr-x
21 root root
4096 May
25
17 :
37 ..
drwxrwxrwx
2 nobody nogroup
6 May
25
18 :
45 default-test-claim-pvc-bdf41489-abe4-
4508 -8adc-74e80f70c626
已创建一个遵循命名约定namespace-pvc_name-pv_name的新目录。 该目录最初是空的。 您可以创建一个测试容器,以通过NFS挂载该目录并对其进行写入。
首先,如果您的群集正在使用Raspberry Pis或其他基于ARM的主机,则需要修改test-pod.yaml文件以使用为ARM主机创建的busybox映像。 默认值将从gcr.io注册表中提取,但没有用于sh二进制文件的正确体系结构,从而导致“ exec格式”错误。 如果您的Kubernetes集群在x86_64主机上运行,则可以跳过此步骤。
更改test-pod.yaml文件以使用docker.io/aarch64/busybox:latest容器映像。 您的文件应如下所示:
kind
: Pod
apiVersion
: v1
metadata :
name
: test-pod
spec :
containers :
- name
: test-pod
image
: docker.io/aarch64/busybox:latest
# image: gcr.io/google_containers/busybox:1.24
command
:
-
"/bin/sh"
args
:
-
"-c"
-
"touch /mnt/SUCCESS && exit 0 || exit 1"
volumeMounts :
- name
: nfs-pvc
mountPath
:
"/mnt"
restartPolicy
:
"Never"
volumes :
- name
: nfs-pvc
persistentVolumeClaim :
claimName
: test-claim
文件中描述的Pod将创建一个busybox容器,将NFS卷从test-claim持久卷安装到容器内的/mnt ,并创建一个名为SUCCESS的文件。
# Creae the test pod container
$ kubectl create
-f test-pod.yaml
pod
/ test-pod created
# Validate the container ran without problem
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-6ddfb9bb6d-x4zwt
1
/
1 Running
0 20m
test-pod
0
/
1 Completed
0 65s
如果容器正确运行且状态为Completed ,则检查NFS服务器上卷的内容:
# From the NFS server, within the directory for the PVC
$
ls default-test-claim-pvc-bdf41489-abe4-
4508 -8adc-74e80f70c626
/
SUCCESS
确实成功! 该Pod能够挂载由NFS客户端供应商创建的NFS卷并对其进行写入!
使用kubectl delete命令清理测试容器和PVC:
# Cleanup the test-pod pod
$ kubectl delete po test-pod
pod
"test-pod" deleted
# Cleanup the test-claim pvc
$ kubectl delete pvc test-claim
persistentvolumeclaim
"test-claim" deleted
调高音量
由于有了NFS客户端供应商和NFS服务器,您现在可以通过创建PVC请求永久卷与Pod一起使用,并且声明将自动填充动态供应的NFS卷。 在大多数方面,这反映了Kubernetes如何与大型公共云中的动态预配置器一起使用,并允许您使用与公共云提供商相同的工作流程。 实际上,存储类的一个好处是在PVC和卷提供程序之间创建了抽象。 这使您可以在内部私有云和任何公共云提供程序之间使用具有相同名称和不同提供程序的存储类,从而使在它们之间的工作负载“移动”变得更加容易。
通过使用NFS,您也可以支持对卷的多次读取和多次写入操作,从而允许多个Pod同时使用这些卷。 如前所述,这非常适合负载平衡的Web服务器或类似服务,并允许您同时在多个节点上扩展服务。
最重要的是,NFS客户端预配器是自动的,可以在NFS导出中动态创建卷,因此不必提前手动进行预配!
试一试新的NFS客户端供应商,并创建一些需要持久存储的项目。 也许尝试(无耻地插入插件) 在Kubernetes上部署InfluxDB和Grafana来收集Twitter统计信息 。
翻译自: https://opensource.com/article/20/6/kubernetes-nfs-client-provisioning
raspberry pi