问题

明天在通过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: v1kind: PersistentVolumemetadata:  name: es-data-holder-01spec:  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 the hostDir 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"