背景
Javashop電商系統的商品索引是使用的elasticsearch,對于高可用的要求有兩個重要的考量:
1、集群化
2、可擴容
3、冗災
冗災就要實作es的持久化,要考慮到es宕機的情況,當es因不可抗因素掛掉了,當我們再恢復了es的運行后,商品索引也要隨之 一起恢復,
本文著重討論elasticsearch的持久化部署方案,當然提供在方案也支持了集群及擴容,
思路
1、資料的存盤
在k8s中的持久化部署不可避免的要用到持久卷,我們采用nfs方式的持久卷來存盤es資料,
持久卷的詳細介紹請見這里:
https://kubernetes.io/docs/concepts/storage/persistent-volumes/
2、節點規劃
默認啟動5個節點,3主2資料,
根據es官方推薦每個節點的智能要分離,因此maseter節點不存盤資料,只用來協調,
3、多節點的權限問題
es的資料目錄默認只允許一個節點訪問,但在k8s上采用了持久卷,所有節點的資料都存盤在這個卷上,這會導致es的訪問權限問題,
報錯如下:
java.io.IOException: failed to obtain lock on /usr/share/elasticsearch/data/nodes/0",
當然可以通過更改es的配置max_local_storage_nodes來允許多個節點訪問同一個資料目錄,但es官方不推薦這樣做,
所以我們的方案是更改每個節點的資料存盤目錄來解決
ps:指定es配置項path.data來實作
舉例說明:
| 節點名 | 存盤目錄 |
| es-data-1 | /usr/share/elasticsearch/data/es-data-1 |
| es-data-2 | /usr/share/elasticsearch/data/es-data-2 |
部署程序
一、pv(持久卷的建立)
先要建立nfs服務器
對于持久卷的結構規劃如下:
| 目錄 | 內容 |
|---|---|
| /nfs/data/esmaster | es master節點的資料 |
| /nfs/data/esdata | es 資料節點的資料 |
關于索引的磁盤占用:
請根據業務的資料量情況來規劃持久卷硬體的情況
根據我們實際測算1000個商品大約需要1MB/每節點
默認情況
在默認的規劃中,我們使用使用k8s的master節點作為nfs服務器,為上述卷準備了10G的空間,請確保k8s master node 不少于10G的空閑磁盤,
請根據您的具體業務情況選擇nfs服務器,如果條件允許最好是獨立的nfs服務器,
根據如上規劃建立nfs服務:
#master節點安裝nfs
yum -y install nfs-utils
#創建nfs目錄
mkdir -p /nfs/data/{mqdata,esmaster,esdata}
#修改權限
chmod -R 777 /nfs/data/
#編輯export檔案
vim /etc/exports
粘貼如下內容:
/nfs/data/esmaster *(rw,no_root_squash,sync)
/nfs/data/esdata *(rw,no_root_squash,sync)
#配置生效
exportfs -r
#查看生效
exportfs
#啟動rpcbind、nfs服務
systemctl restart rpcbind && systemctl enable rpcbind
systemctl restart nfs && systemctl enable nfs
#查看 RPC 服務的注冊狀況
rpcinfo -p localhost
#showmount測驗,這里的ip輸入master節點的局域網ip
showmount -e <your ip>
如果成功可以看到可被掛載的目錄:
# showmount -e 172.17.14.73
Export list for 172.17.14.73:
/nfs/data/esmaster *
/nfs/data/mqdata *
接下來,要在每一個節點上安裝nfs服務以便使k8s可以掛載nfs目錄
#所有node節點安裝客戶端
yum -y install nfs-utils
systemctl start nfs && systemctl enable nfs
這樣就為k8s的持久卷做好了準備,
建立持久卷
有了nfs的準備,我就可以建立持久卷了:
我們分享了javashop內部使用的yaml倉庫供大家參考:
https://gitee.com/enation/elasticsearch-on-k8s
在您的k8s maseter節點服務器上 clone我們準備好的yaml檔案
git clone https://gitee.com/javashop/elasticsearch-on-k8s
修改yaml目錄中的pv.yaml
修改其中的server配置為nfs服務器的IP:
nfs:
server: 192.168.1.100 #這里請寫nfs服務器的ip
在k8s master節點上執行下面的命令創建namespace:
kubectl create namespace ns-elasticsearch
通過下面的命令建立持久卷:
kubectl create -f pv.yaml
通過以下命令查看持久卷是否建立成功:
kubectl get pv
部署elasticsearch
執行下面的命令創建es集群
kubectl create -f elasticsearch.yaml
通過以上部署我們建立了一個ns-elasticsearch的namespace,并在其中創建了相應的pvc、角色賬號,有狀態副本集以及服務,
有狀態副本集:

服務:

鏡像
使用的是javashop自己基于es:6做的,加入了ik分詞插件,其他沒有變化,
服務
我們默認開啟了對外nodeport埠,對應關系:
32000->9200
32100->9300
k8s內部可以通過下面的服務名稱訪問:
elasticsearch-api-service.ns-elasticsearch:9300
elasticsearch-service.ns-elasticsearch:9200
等待容器都啟動成功后驗證,
驗證
1、生成索引
2、洗掉副本集:
kubectl delete -f elasticsearch.yaml
3、建立副本集
kubectl create -f elasticsearch.yaml
4、查看之前的索引是否恢復
關鍵技術點
1、集群發現:
- name: "discovery.zen.ping.unicast.hosts"
value: "elasticsearch-discovery"
建立了elasticsearch-discovery服務
2、映射持久卷
映射到:/usr/share/elasticsearch/data/
3、自定義資料目錄
- name: "path.data"
value: "/usr/share/elasticsearch/data/$(MY_POD_NAME)"
其中MY_POD_NAME是讀取的容器名稱,通過有狀態副本集保證唯一性的系結:
- name: MY_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
歡迎關注Javashop技術分享公眾號,觀看更多的視頻講解:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/21118.html
標籤:其他
