因为Elasticsearch需要保持数据在固定的磁盘上,属于有状态的应用服务,因此采用k8s的StatefulSet模式部署。
创建PersistentVolumes和Claim
#es-persistent-volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: es-nfs-pv
labels:
pv: es-nfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /data/nfs/es/
server: 192.168.1.1 #要挂载卷的所在机器
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: es-nfs-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
selector:
matchLabels:
pv: "es-nfs-pv"
deployment-es.yaml文件内容:
kind: StatefulSet
metadata:
name: elasticsearch-sts
spec:
selector:
matchLabels:
app: es # has to match .spec.template.metadata.labels
serviceName: "elasticsearch-svc" #声明它属于哪个Headless Service.
replicas: 1 # by default is 1
template:
metadata:
labels:
app: es # has to match .spec.selector.matchLabels
spec:
terminationGracePeriodSeconds: 10
volumes:
- name: data-storage
persistentVolumeClaim:
claimName: es-nfs-pvc #和之前的PersistentVolumeClaim的name一致
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:7.9.2
ports:
- containerPort: 9200
name: es-cli
- containerPort: 9300
name: es-iner
env:
- name: discovery.type
value: single-node
- name: http.cors.enabled
value: "true"
- name: http.cors.allow-origin
value: "*"
volumeMounts:
- mountPath: "/tmp/data"
name: data-storage
---
apiVersion: v1
kind: Service
metadata:
name: elasticsearch-svc
labels:
app: elasticsearch-svc
spec:
type: NodePort
ports:
- port: 9200
nodePort: 30920 #对外暴露的访问端口,需要在30000~32727范围内。
name: clientport
selector:
app: es
master节点上执行:
kubectl apply -f es-persistent-volume.yaml
kubectl apply -f deployment-es.yaml
看看执行后的结果:
#查看部署的statefulset
$ kubectl get sts
NAME READY AGE
elasticsearch-sts 1/1 1m
#查看service
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch-svc NodePort 10.101.52.134 <none> 9200:30920/TCP 1m
#查看启动的pod
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
elasticsearch-sts-0 1/1 Running 0 1m
这样部署好之后就可以通过masterIp+nodePort的方式访问Elasticsearch服务了.
- 插入数据:
$ curl -X PUT 127.0.0.1:30920/test/_doc/1?pretty -H 'Content-Type: application/json' -d '{"id":1, "msg":"test"}'
{
"_index" : "test",
"_type" : "_doc",
"_id" : "1",
"_version" : 4,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 3,
"_primary_term" : 1
}
- 查询:
$ curl -X GET 127.0.0.1:30920/test/_doc/1?pretty
{
"_index" : "test",
"_type" : "_doc",
"_id" : "1",
"_version" : 4,
"_seq_no" : 3,
"_primary_term" : 1,
"found" : true,
"_source" : {
"id" : 1,
"msg" : "test"
}
}
解决挂载遇到的错误
- nfs挂载错误“mount: wrong fs type, bad option, bad superblock on ...”,需要在挂载的服务机上启动nfs服务。
安装nfs-utils:
yum install nfs-utils
(各个node节点也要安装nfs-utils,不然也会mount失败)。
启动nfs服务:
service nfs start
- “mount.nfs: access denied by server while mounting”的错误,要export对应的挂载点。
在/etc/exports添加如下内容:
/home/nfs/data *(insecure,rw,sync,no_root_squash)
#这里最好不要用async,不然可能会失败
- 要有对挂载目录的读写权限
4.额外的,挂载命令示例: sudo mount -t nfs 192.168.1.1:/data/nfs /mnt/nfs