无法将数据保存在 Kubernetes 中的持久卷上(Google 云)
Can't keep data on my persistent volume in Kubernetes (Google Cloud)
我在 Google 云上的 Kubernetes 集群上有一个 Redis pod。
我已经建立了 pv 和声明。
kind: PersistentVolume
apiVersion: v1
metadata:
name: redis-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: my-size
accessModes:
- ReadWriteOnce
hostPath:
path: "/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: postgres
name: redis-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: my size
我也安装在我的 deployment.yaml
volumeMounts:
- mountPath: /data
name: redis-pv-claim
volumes:
- name: redis-pv-claim
persistentVolumeClaim:
claimName: redis-pv-claim
我在 运行 描述 pod
时看不到任何错误
Volumes:
redis-pv-claim:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: redis-pv-claim
ReadOnly: false
但它就是不能保存任何密钥。每次部署后,“/data”文件夹都是空的。
我的 NFS 现在是活动的,但我仍然无法保存数据。
描述 PVC
Namespace: my namespace
StorageClass: nfs-client
Status: Bound
Volume: pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-class: nfs-client
volume.beta.kubernetes.io/storage-provisioner: cluster.local/ext1-nfs-client-provisioner
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 1Gi
Access Modes: RWX
VolumeMode: Filesystem
Mounted By: my grafana pod
Events: <none>
Describe pod 给我一个错误。
Warning FailedMount 18m kubelet, gke-devcluster-pool-1-36e6a393-rg7d MountVolume.SetUp failed for volume "pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3" : mount failed: exit status 1
Mounting command: systemd-run
Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/8f7b6630-ed9b-427a-9ada-b75e1805ed60/volumes/kubernetes.io~nfs/pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3 --scope -- /
home/kubernetes/containerized_mounter/mounter mount -t nfs 192.168.1.21:/mnt/nfs/development-test-claim-pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3 /var/lib/kubelet/pods/8f7b6630-ed9b-427a-9ada-b75e1805ed60
/volumes/kubernetes.io~nfs/pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3
Output: Running scope as unit: run-ra5925a8488ef436897bd44d526c57841.scope
Mount failed: mount failed: exit status 32
Mounting command: chroot
发生的事情是,当您有多个节点时,使用 PVC 在 pods 之间共享文件并不是最好的方法。
PVC 可以在位于同一节点的 pods 之间共享文件。因此,如果我有多个节点,有时我可能会觉得我的文件没有正确存储。
您的理想解决方案是使用任何可用的 DSF 解决方案。在您的问题中,您提到您正在使用 GCP,但不清楚您是在使用 GKE 还是在计算实例之上创建了集群。
如果您使用的是 GKE,您是否已查看 this 文档?请告诉我。
如果您有权访问您的节点,最简单的设置是在您的一个节点中创建一个 NFS 服务器,并使用 nfs-client-provisioner 提供从您的 pods.
我使用这种方法已经有一段时间了,效果非常好。
1 - 在我的主节点上安装和配置 NFS 服务器(Debian Linux,这可能会根据您的 Linux 发行版而改变):
在安装 NFS 内核服务器之前,我们需要更新系统的存储库索引:
$ sudo apt-get update
现在,运行为了在您的系统上安装 NFS 内核服务器,请执行以下命令:
$ sudo apt install nfs-kernel-server
创建导出目录
$ sudo mkdir -p /mnt/nfs_server_files
由于我们希望所有客户端都可以访问该目录,因此我们将通过以下命令删除导出文件夹的限制性权限(根据您的安全策略,这可能因您的设置而异):
$ sudo chown nobody:nogroup /mnt/nfs_server_files
$ sudo chmod 777 /mnt/nfs_server_files
通过 NFS 导出文件将服务器访问权限分配给客户端
$ sudo nano /etc/exports
在此文件中,添加一个新行以允许从其他服务器访问您的共享。
/mnt/nfs_server_files 10.128.0.0/24(rw,sync,no_subtree_check)
您可能希望在共享中使用不同的选项。 10.128.0.0/24是我的k8s内网。
导出共享目录并重启服务,确保所有配置文件正确。
$ sudo exportfs -a
$ sudo systemctl restart nfs-kernel-server
检查所有活跃股:
$ sudo exportfs
/mnt/nfs_server_files
10.128.0.0/24
2 - 在我的所有工作节点上安装 NFS 客户端:
$ sudo apt-get update
$ sudo apt-get install nfs-common
此时您可以进行测试以检查您是否可以从您的工作节点访问您的共享:
$ sudo mkdir -p /mnt/sharedfolder_client
$ sudo mount kubemaster:/mnt/nfs_server_files /mnt/sharedfolder_client
请注意,此时您可以使用主节点的名称。 K8s 在这里负责 DNS。
检查卷是否按预期安装并创建一些文件夹和文件以确保一切正常。
$ cd /mnt/sharedfolder_client
$ mkdir test
$ touch file
返回到您的主节点并检查这些文件是否在 /mnt/nfs_server_files 文件夹中。
3 - 安装 NFS 客户端配置程序。
使用 helm 安装 provisioner:
$ helm install --name ext --namespace nfs --set nfs.server=kubemaster --set nfs.path=/mnt/nfs_server_files stable/nfs-client-provisioner
注意我已经为它指定了一个名称空间。
检查它们是否 运行ning:
$ kubectl get pods -n nfs
NAME READY STATUS RESTARTS AGE
ext-nfs-client-provisioner-f8964b44c-2876n 1/1 Running 0 84s
此时我们有一个名为 nfs-client 的存储类:
$ kubectl get storageclass -n nfs
NAME PROVISIONER AGE
nfs-client cluster.local/ext-nfs-client-provisioner 5m30s
我们需要创建一个 PersistentVolumeClaim:
$ more nfs-client-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
namespace: nfs
name: test-claim
annotations:
volume.beta.kubernetes.io/storage-class: "nfs-client"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
$ kubectl apply -f nfs-client-pvc.yaml
检查状态(预计绑定):
$ kubectl get persistentvolumeclaim/test-claim -n nfs
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-claim Bound pvc-e1cd4c78-7c7c-4280-b1e0-41c0473652d5 1Mi RWX nfs-client 24s
4 - 创建一个简单的 pod 来测试我们是否可以 read/write 退出 NFS 共享:
使用这个 yaml 创建一个 pod:
apiVersion: v1
kind: Pod
metadata:
name: pod0
labels:
env: test
namespace: nfs
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-pvc
mountPath: "/mnt"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-claim
$ kubectl apply -f pod.yaml
让我们列出 pod 上所有已安装的卷:
$ kubectl exec -ti -n nfs pod0 -- df -h /mnt
Filesystem Size Used Avail Use% Mounted on
kubemaster:/mnt/nfs_server_files/nfs-test-claim-pvc-a2e53b0e-f9bb-4723-ad62-860030fb93b1 99G 11G 84G 11% /mnt
正如我们所见,我们在 /mnt 上安装了一个 NFS 卷。 (注意路径很重要kubemaster:/mnt/nfs_server_files/nfs-test-claim-pvc-a2e53b0e-f9bb-4723-ad62-860030fb93b1
)
让我们检查一下:
root@pod0:/# cd /mnt
root@pod0:/mnt# ls -la
total 8
drwxrwxrwx 2 nobody nogroup 4096 Nov 5 08:33 .
drwxr-xr-x 1 root root 4096 Nov 5 08:38 ..
它是空的。让我们创建一些文件:
$ for i in 1 2; do touch file$i; done;
$ ls -l
total 8
drwxrwxrwx 2 nobody nogroup 4096 Nov 5 08:58 .
drwxr-xr-x 1 root root 4096 Nov 5 08:38 ..
-rw-r--r-- 1 nobody nogroup 0 Nov 5 08:58 file1
-rw-r--r-- 1 nobody nogroup 0 Nov 5 08:58 file2
现在让我们看看 NFS 服务器(主节点)上的这些文件在哪里:
$ cd /mnt/nfs_server_files
$ ls -l
total 4
drwxrwxrwx 2 nobody nogroup 4096 Nov 5 09:11 nfs-test-claim-pvc-4550f9f0-694d-46c9-9e4c-7172a3a64b12
$ cd nfs-test-claim-pvc-4550f9f0-694d-46c9-9e4c-7172a3a64b12/
$ ls -l
total 0
-rw-r--r-- 1 nobody nogroup 0 Nov 5 09:11 file1
-rw-r--r-- 1 nobody nogroup 0 Nov 5 09:11 file2
这是我们刚刚在 pod 中创建的文件!
如果此解决方案对您有帮助,请告诉我。
我在 Google 云上的 Kubernetes 集群上有一个 Redis pod。 我已经建立了 pv 和声明。
kind: PersistentVolume
apiVersion: v1
metadata:
name: redis-pv
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: my-size
accessModes:
- ReadWriteOnce
hostPath:
path: "/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
app: postgres
name: redis-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: my size
我也安装在我的 deployment.yaml
volumeMounts:
- mountPath: /data
name: redis-pv-claim
volumes:
- name: redis-pv-claim
persistentVolumeClaim:
claimName: redis-pv-claim
我在 运行 描述 pod
时看不到任何错误Volumes:
redis-pv-claim:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: redis-pv-claim
ReadOnly: false
但它就是不能保存任何密钥。每次部署后,“/data”文件夹都是空的。
我的 NFS 现在是活动的,但我仍然无法保存数据。
描述 PVC
Namespace: my namespace
StorageClass: nfs-client
Status: Bound
Volume: pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-class: nfs-client
volume.beta.kubernetes.io/storage-provisioner: cluster.local/ext1-nfs-client-provisioner
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 1Gi
Access Modes: RWX
VolumeMode: Filesystem
Mounted By: my grafana pod
Events: <none>
Describe pod 给我一个错误。
Warning FailedMount 18m kubelet, gke-devcluster-pool-1-36e6a393-rg7d MountVolume.SetUp failed for volume "pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3" : mount failed: exit status 1
Mounting command: systemd-run
Mounting arguments: --description=Kubernetes transient mount for /var/lib/kubelet/pods/8f7b6630-ed9b-427a-9ada-b75e1805ed60/volumes/kubernetes.io~nfs/pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3 --scope -- /
home/kubernetes/containerized_mounter/mounter mount -t nfs 192.168.1.21:/mnt/nfs/development-test-claim-pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3 /var/lib/kubelet/pods/8f7b6630-ed9b-427a-9ada-b75e1805ed60
/volumes/kubernetes.io~nfs/pvc-5d278b27-a51e-4262-8c1b-68b290b21fc3
Output: Running scope as unit: run-ra5925a8488ef436897bd44d526c57841.scope
Mount failed: mount failed: exit status 32
Mounting command: chroot
发生的事情是,当您有多个节点时,使用 PVC 在 pods 之间共享文件并不是最好的方法。
PVC 可以在位于同一节点的 pods 之间共享文件。因此,如果我有多个节点,有时我可能会觉得我的文件没有正确存储。
您的理想解决方案是使用任何可用的 DSF 解决方案。在您的问题中,您提到您正在使用 GCP,但不清楚您是在使用 GKE 还是在计算实例之上创建了集群。
如果您使用的是 GKE,您是否已查看 this 文档?请告诉我。
如果您有权访问您的节点,最简单的设置是在您的一个节点中创建一个 NFS 服务器,并使用 nfs-client-provisioner 提供从您的 pods.
我使用这种方法已经有一段时间了,效果非常好。
1 - 在我的主节点上安装和配置 NFS 服务器(Debian Linux,这可能会根据您的 Linux 发行版而改变):
在安装 NFS 内核服务器之前,我们需要更新系统的存储库索引:
$ sudo apt-get update
现在,运行为了在您的系统上安装 NFS 内核服务器,请执行以下命令:
$ sudo apt install nfs-kernel-server
创建导出目录
$ sudo mkdir -p /mnt/nfs_server_files
由于我们希望所有客户端都可以访问该目录,因此我们将通过以下命令删除导出文件夹的限制性权限(根据您的安全策略,这可能因您的设置而异):
$ sudo chown nobody:nogroup /mnt/nfs_server_files
$ sudo chmod 777 /mnt/nfs_server_files
通过 NFS 导出文件将服务器访问权限分配给客户端
$ sudo nano /etc/exports
在此文件中,添加一个新行以允许从其他服务器访问您的共享。
/mnt/nfs_server_files 10.128.0.0/24(rw,sync,no_subtree_check)
您可能希望在共享中使用不同的选项。 10.128.0.0/24是我的k8s内网。
导出共享目录并重启服务,确保所有配置文件正确。
$ sudo exportfs -a
$ sudo systemctl restart nfs-kernel-server
检查所有活跃股:
$ sudo exportfs
/mnt/nfs_server_files
10.128.0.0/24
2 - 在我的所有工作节点上安装 NFS 客户端:
$ sudo apt-get update
$ sudo apt-get install nfs-common
此时您可以进行测试以检查您是否可以从您的工作节点访问您的共享:
$ sudo mkdir -p /mnt/sharedfolder_client
$ sudo mount kubemaster:/mnt/nfs_server_files /mnt/sharedfolder_client
请注意,此时您可以使用主节点的名称。 K8s 在这里负责 DNS。 检查卷是否按预期安装并创建一些文件夹和文件以确保一切正常。
$ cd /mnt/sharedfolder_client
$ mkdir test
$ touch file
返回到您的主节点并检查这些文件是否在 /mnt/nfs_server_files 文件夹中。
3 - 安装 NFS 客户端配置程序。
使用 helm 安装 provisioner:
$ helm install --name ext --namespace nfs --set nfs.server=kubemaster --set nfs.path=/mnt/nfs_server_files stable/nfs-client-provisioner
注意我已经为它指定了一个名称空间。 检查它们是否 运行ning:
$ kubectl get pods -n nfs
NAME READY STATUS RESTARTS AGE
ext-nfs-client-provisioner-f8964b44c-2876n 1/1 Running 0 84s
此时我们有一个名为 nfs-client 的存储类:
$ kubectl get storageclass -n nfs
NAME PROVISIONER AGE
nfs-client cluster.local/ext-nfs-client-provisioner 5m30s
我们需要创建一个 PersistentVolumeClaim:
$ more nfs-client-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
namespace: nfs
name: test-claim
annotations:
volume.beta.kubernetes.io/storage-class: "nfs-client"
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
$ kubectl apply -f nfs-client-pvc.yaml
检查状态(预计绑定):
$ kubectl get persistentvolumeclaim/test-claim -n nfs
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-claim Bound pvc-e1cd4c78-7c7c-4280-b1e0-41c0473652d5 1Mi RWX nfs-client 24s
4 - 创建一个简单的 pod 来测试我们是否可以 read/write 退出 NFS 共享:
使用这个 yaml 创建一个 pod:
apiVersion: v1
kind: Pod
metadata:
name: pod0
labels:
env: test
namespace: nfs
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-pvc
mountPath: "/mnt"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-claim
$ kubectl apply -f pod.yaml
让我们列出 pod 上所有已安装的卷:
$ kubectl exec -ti -n nfs pod0 -- df -h /mnt
Filesystem Size Used Avail Use% Mounted on
kubemaster:/mnt/nfs_server_files/nfs-test-claim-pvc-a2e53b0e-f9bb-4723-ad62-860030fb93b1 99G 11G 84G 11% /mnt
正如我们所见,我们在 /mnt 上安装了一个 NFS 卷。 (注意路径很重要kubemaster:/mnt/nfs_server_files/nfs-test-claim-pvc-a2e53b0e-f9bb-4723-ad62-860030fb93b1
)
让我们检查一下:
root@pod0:/# cd /mnt
root@pod0:/mnt# ls -la
total 8
drwxrwxrwx 2 nobody nogroup 4096 Nov 5 08:33 .
drwxr-xr-x 1 root root 4096 Nov 5 08:38 ..
它是空的。让我们创建一些文件:
$ for i in 1 2; do touch file$i; done;
$ ls -l
total 8
drwxrwxrwx 2 nobody nogroup 4096 Nov 5 08:58 .
drwxr-xr-x 1 root root 4096 Nov 5 08:38 ..
-rw-r--r-- 1 nobody nogroup 0 Nov 5 08:58 file1
-rw-r--r-- 1 nobody nogroup 0 Nov 5 08:58 file2
现在让我们看看 NFS 服务器(主节点)上的这些文件在哪里:
$ cd /mnt/nfs_server_files
$ ls -l
total 4
drwxrwxrwx 2 nobody nogroup 4096 Nov 5 09:11 nfs-test-claim-pvc-4550f9f0-694d-46c9-9e4c-7172a3a64b12
$ cd nfs-test-claim-pvc-4550f9f0-694d-46c9-9e4c-7172a3a64b12/
$ ls -l
total 0
-rw-r--r-- 1 nobody nogroup 0 Nov 5 09:11 file1
-rw-r--r-- 1 nobody nogroup 0 Nov 5 09:11 file2
这是我们刚刚在 pod 中创建的文件!
如果此解决方案对您有帮助,请告诉我。