问题
今天在通过kubernetes部署elasticsearch的过程中出现一个问题,特此记录一下。因为elasticsearch是有状态应用,需要使用持久化存储,手头既没有云存储,也没有nfs,cephfs之类的存储。kubernetes给的elasticsearch的yaml资源文件默认的是emptydir方式,并且文档强调:
Storage
The Elasticsearch StatefulSet will use the EmptyDir volume to store data. EmptyDir is erased when the pod terminates, here it is used only for testing purposes. Important: please change the storage to persistent volume claim before actually using this StatefulSet in your setup!
说白了,这块需要自由发挥,选择适合自己的持久化存储。所以理所应当使用本地磁盘,Local PV的方式,PV的资源文件如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: es-data-holder-01
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /home/k8s/localpv # 节点上的目录
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- kubernetes-node03
其中指定了/home/k8s/localpv
目录作为存储目录,这些都不是关键点,关键点在于,最后elasticsearch的pod启动时会报错:
Error: MountVolume.NewMounter initialization failed for volume “local-pv-xxxxx” : path “/home/k8s/localpv” does not exist
找不到/home/k8s/localpv
路径。
原因
因为我的Kubernetes集群是通过Rancher安装的RKE集群,并不是原生通过Kubeadm安装的,所以集群组件都运行在Docker容器内,所以kubelet 运行在容器内部,无法读到 Node 节点上的路径。
官方FAQ也说明了这个问题
Volume does not exist with containerized kubelet
If your kubelet is running in a container, it may not be able to access the path on the host.
In order to allow the kubelet to access the path on the host, you must prefix
hostDir
with the prefix of the host filesystem in the kubelet container or mount the directory of the local volumes into the kubelet container at the same path.For example, if the root filesystem of the host is mounted at
/rootfs
in the kubelet container, you need to prefix thehostDir
with/rootfs
. This requires recreating the local PV objects. You can delete them all and wait for them to be discovered again.Another solution is to add a bind in the kubelet deployment configuration to mount the parent directory of local volumes into the kubelet container at the same path. This requires restarting the kubelet container.
For Rancher clusters, users must configure additional local volumes (or the parent directory) via Extra Binds.
解决方法如下:
services:
kubelet:
extra_binds:
- "/host/dev:/dev"
- "/usr/libexec/kubernetes/kubelet-plugins:/usr/libexec/kubernetes/kubelet-plugins:z"
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。