iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
Software Development

由淺入深來探討Elasticsearch,從基礎語法到底層相關原理系列 第 25

【Day 25】由淺入深來探討Elasticsearch - xpack與多節點叢集架設

  • 分享至 

  • xImage
  •  

經過這兩天的介紹,相信大家對於多節點的叢集有更深的認識
對於yml檔中的一些參數設定也不會覺得那麼陌生

今天主要的目標就是架設多節點的叢集以及相關的知識介紹
會分成幾個部分:

  1. xpack介紹與實際操作
  2. 使用docker架設多節點叢集
  3. 對已經架設好的叢集進行添加與刪除node操作介紹

Xpack介紹與實際操作

xpack是Elastic Stack對於資安與監控,甚至機器學習上的擴展應用
雖然說要使用完整的功能是需要付費的,但是免費的部分其實如果是一般生產環境甚至也是夠用的
並且在8.0版本後,不用做任何額外xpack的設定
ES都會預設幫忙處理好基本basic security部分

我們在使用ES時可能有幾點事項需要考慮

  1. 主機的安全性本身:
    • 不是任何身份的請求都可以傳入架設的主機中
    • 如果有使用過一些如nginx, uwsgi或是docker等服務來說,ES也一樣建議不要用root用戶來運行
      • 避免萬一服務被入侵時,整台主機的所有權限都丟失
  2. 通訊的安全性:
    • node之前通訊的安全性
    • 整個cluster對外HTTP的安全性
  3. 資料管理的安全性:
    • 管理資料的權限以及對於身份的驗證
    • 資料毀損時的備份或是修復

在通訊的安全與身份驗證的部分,我們今天介紹如何利用xpack做實現

主要可以分成三個層級

  • Minimal security:
    • 使用elasticsearch的用戶權限
    • kibana要連接ES所使用的帳號密碼
  • Basic security:
    • 建立CA
    • 使用CA建立憑證,用於node之間TCP所需之TLS
  • Basic security + HTTPS
    • 外部連結所需之HTTPS
      https://ithelp.ithome.com.tw/upload/images/20230927/20161866xqHTmdOCKG.png
      圖源:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/configuring-stack-security.html

我們開始之前先做一些步驟:

  1. 準備好三個節點,利用不同port來模擬不同的主機開啟
    • 一個其實也沒關係,只是順便展示yml的設定,跟前幾天的內容呼應
      https://ithelp.ithome.com.tw/upload/images/20230927/20161866x1EUqnKaQ4.png
  2. 修改yml檔
vim config/elasticsearch.yml
  1. 三個節點的yml檔案如下
// node-1
cluster.name: test_xpack
node.name: test_node01
discovery.seed_hosts:
  - localhost:9300
  - localhost:9301
  - localhost:9302
cluster.initial_master_nodes:
  - test_node01
  - test_node02
  - test_node03
xpack.security.enabled: false
network.host: localhost
http.port: 9200
transport.port: 9300

// node-2
cluster.name: test_xpack
node.name: test_node02
discovery.seed_hosts:
  - localhost:9300
  - localhost:9301
  - localhost:9302
cluster.initial_master_nodes:
  - test_node01
  - test_node02
  - test_node03
xpack.security.enabled: false
network.host: localhost
http.port: 9201
transport.port: 9301

// node-3
cluster.name: test_xpack
node.name: test_node03
discovery.seed_hosts:
  - localhost:9300
  - localhost:9301
  - localhost:9302
cluster.initial_master_nodes:
  - test_node01
  - test_node02
  - test_node03
xpack.security.enabled: false
network.host: localhost
http.port: 9202
transport.port: 9302
  1. 設置kibana的yml檔
elasticsearch.hosts: ["http://localhost:9200"]
elasticsearch.username: "kibana_system"

接下來我們就對這三層來一一做示範

建立minimal security:

這部分我們要為ES設定用戶的密碼

  1. 每個節點中yml檔中更改xpack security,設置為true
xpack.security.enabled: true
  1. 儲存後,啟動3個節點
./bin/elasticsearch
  1. 此時等log跑出security is enabled
[2023-09-27T17:09:40,413][INFO ][o.e.x.s.Security         ] [test_node02] Security is enabled
  1. 接著我們可以在瀏覽器或是用curl來呼叫localhost:9200
  • 如果是瀏覽器會希望我們輸入用戶帳密,這邊我們直接取消
{
	"error":{
		"root_cause":[
			{
				"type":"security_exception",
				"reason":"missing authentication credentials for REST request [/]",
				"header":{
				"WWW-Authenticate":[
				"Basic realm=\"security\" charset=\"UTF-8\"",
				"ApiKey"
					]
				}
			}
		],
		"type":"security_exception",
		"reason":"missing authentication credentials for REST request [/]",
		"header":{
			"WWW-Authenticate":[
				"Basic realm=\"security\" charset=\"UTF-8\"",
				"ApiKey"
			]
		}
	},
	"status":401
}
  1. 可是我也不知道帳號密碼啊,剛剛yml檔也沒特別設定
  2. 我們可以去看config資料夾中有多一個keystore檔
  3. 我們list出底下的資料,再用show處理這個檔案,我們就能拿到系統建立的密碼
    • 預設狀況ES會給我們elastic這個系統的帳號
      • 生產環境下應該要再額外創建其他用戶然後設置權限
        https://ithelp.ithome.com.tw/upload/images/20230927/20161866DQwqzHl2Te.png
  4. 那我們再次使用密碼登入,就可以重新登入
    • 如果有失敗的話換其他node的port看看
    • 如果要重新設置密碼:./bin/elasticsearch-reset-password
{
  "name" : "test_node02",
  "cluster_name" : "test_xpack",
  "cluster_uuid" : "ugg-hSz_Rz6_Y7X6PjOMcw",
  "version" : {
    "number" : "8.9.1",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "a813d015ef1826148d9d389bd1c0d781c6e349f0",
    "build_date" : "2023-08-10T05:02:32.517455352Z",
    "build_snapshot" : false,
    "lucene_version" : "9.7.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}
  1. 我們建立kibana要連到ES所需要的帳號密碼
    • 我們剛剛都沒有開啟過kibana,所以我們可以自己存密碼進去
// 先create出新的keystore檔
./bin/kibana-keystore create

// add 設定的參數名稱
./bin/kibana-keystore add elasticsearch.password
  1. 最後啟動kibana
bin/kibana

建立Basic security:

在這部分我們要為node的節點溝通時能夠加密與驗證
既然需要憑證,我們也需要能發放憑證的Certificate Authority(CA)

所以步驟大致上為:

  • 建立CA
  • 使用CA建立憑證並放到node中
  • 添加設定到yml,並重啟節點
  1. 建立CA
./bin/elasticsearch-certutil ca

https://ithelp.ithome.com.tw/upload/images/20230927/20161866Tlizx7i5Ay.png

  • 前者決定憑證輸出時的檔案檔名,這邊可以直接enter不修改
  • 後者設定使用權限密碼,這邊可以enter先跳過不設定
  • 產出的ca,可以幫助我們來建立憑證
By default the 'ca' mode produces a single PKCS#12 output file which holds:
    * The CA certificate
    * The CA's private key

https://ithelp.ithome.com.tw/upload/images/20230927/20161866XVxSQQ8c75.png
2. 接著用ca來建立憑證
- 用cert表示我們要建立x.509的憑證與密鑰
- 後面 —ca則指定要用什麼ca

./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

https://ithelp.ithome.com.tw/upload/images/20230927/20161866DtWBkcbrb5.png

  • 一樣密碼跟確認密碼都是enter,並且我們要不更改檔名
  • 建立好後把這些檔案放入config資料夾
  1. 最後在每個節點的yml檔中添加設定,並重啟node
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.client_authentication: required
xpack.security.transport.ssl.keystore.path: elastic-certificates.p12
xpack.security.transport.ssl.truststore.path: elastic-certificates.p12
  • verification_mode: certificate代表我們的憑證是被受信任的CA所簽署,但是沒有做hostname相關認證,要設其他參數可以參考:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-settings.html#transport-tls-ssl-settings
  1. 當我們重啟後,node之間通訊就可以用TLS加密

建立HTTPS:

這一部分我們要建立對外的HTTP layer也能用TLS加密

  1. 一樣用elasticsearch-certutil工具建立
./bin/elasticsearch-certutil http
  1. 輸入後需要做一些設定
1. Generate a CSR? [y/N]
如果想要自己簽署憑證就選n

2. Use an existing CA? 
輸入y,我們剛剛有做CA了

3. CA Path:
輸入elastic-stack-ca.p12所在路徑

4. Password for elastic-stack-ca.p12:
輸入enter

5. For how long should your certificate be valid? [5y]
輸入enter

6. Generate a certificate per node? [y/N]
我們沒有要每個node特製,所以輸入n

7. Enter all the hostnames that you need, one per line.
When you are done, press <ENTER> once more to move on to the next step.
我們輸入localhost

8. Is this correct [Y/n]
輸入y

9. Enter all the IP addresses that you need, one per line.
When you are done, press <ENTER> once more to move on to the next step.
因為是本地,輸入127.0.0.1

10. Do you wish to change any of these options? [y/N]
輸入n

11. If you wish to use a blank password, simply press <enter> at the prompt below.
Provide a password for the "http.p12" file:  [<ENTER> for none]
輸入enter

12. What filename should be used for the output zip file? [/Users/nb050/Downloads/elasticsearch-8.9.1-1/elasticsearch-ssl-http.zip]
不做修改,輸入enter

最後在當前路徑會看到elasticsearch-ssl-http.zip

https://ithelp.ithome.com.tw/upload/images/20230927/20161866jM3GeKNqID.png
解壓縮後有兩個檔案

  • http要使用的p12
  • kibana要連到ES,相當於client要連到ES,現在也要https所以需要驗證
  • 將他們分別丟到kibana跟ES node下面
  1. 添加設定到yml檔,然後重新啟動node
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: http.p12
  1. 因為client端要用HTTPS所以我們也要更改kibana的設定
elasticsearch.hosts: ["https://localhost:9200"]
elasticsearch.ssl.certificate: /path/to/your/client.crt
  1. 最後再啟動kibana就能連上了

當然現在直接下載ES跟kibana後,我們直接啟動的話,就能夠直接透用xpack這些設定了,不用自己手動

Docker架設多節點叢集

接著我們參考官方的文檔來使用docker compose架設ES

  1. 一些比較隱私的設定放.env
ELASTIC_PASSWORD=
// 給預設elastic帳號的密碼

KIBANA_PASSWORD=
// 給預設kibana_system帳號的密碼

STACK_VERSION={version}
// ES要使用的版本

CLUSTER_NAME=docker-cluster
// 要取的cluster name

LICENSE=basic
// 我們在license是用basic版本

ES_PORT=127.0.0.1:9200
// 對外連接,我們也可以寫完整,確保不是隨便的host也可以

KIBANA_PORT=5601
// 我們要連到kibana的port

MEM_LIMIT=1073741824
// 針對自己的機器去設定記憶體大小
  1. 製作docker-compose.yml,因為完整檔案太長了,我這邊就不放了

想看完整的:https://github.com/elastic/elasticsearch/blob/8.10/docs/reference/setup/install/docker/docker-compose.yml

我這邊就提幾個點:

  • setup容器基本上就是在做我們剛剛憑證的動作
    • 先檢查有沒有設定密碼
    • 檢查有沒有ca,沒有的話執行bin/elasticsearch-certutil ca
    • 如果還沒建立憑證,先把所有節點的名稱, ip以及DNS匯集起來
    • 用ca去生成這些節點的憑證
    • 設置檔案的權限,以及將kibana_system的密碼補上
  1. 最後使用docker compose up -d就能在背景執行了

添加與刪除現有叢集的node

添加node到一個exiting cluster

  • 需要為新node添加discovery.seed_hosts,讓他能找到現有的cluster
  • 當ES第一次啟動時,安全自動設定程序將HTTP層綁定到0.0.0.0,但僅將傳輸層綁定到localhost
    • 預設可確保無需任何其他配置即可啟動預設啟用安全性的單節點叢集
  1. 在現有cluster中的node中,製作enrollment token給想加入的node
bin\elasticsearch-create-enrollment-token -s node
  1. 在啟動新節點時,也將enrollment token一起輸入
bin\elasticsearch --enrollment-token <enrollment-token>
  1. 會在config/certs中生產憑證

removing master-eligible nodes

  • 刪除符合主節點資格的節點時,不要同時刪除太多節點
  • 如果目前有7個符合主節點資格的節點,而想減少到三個,則不可馬上停止其中四個節點
    • 只留下三個節點,不到一半投票配置的狀態
    • 導致叢集無法正常運行

實際操作:

  1. 利用排除voting configuration後,ES不會主動將該node添加回voting configuration的特點,發送請求告至ES想刪掉的node
    • 如果想刪除的是master node,刪除node在voting configuration的位置後,他會讓位給其他仍然在voting configuration的node(還沒被刪除的話)
    • 如果是刪除非master-eligible nodes或是刪除的節點沒超過一半,可以不用這樣的API
POST /_cluster/voting_config_exclusions?node_names=node_name&timeout=1m
// timeout預設30秒
  1. 可以檢查在排除名單中是否有我們剛剛提名的node
    • 因為這個名單是有上限(10),並且是永久的
    • 確定操作完後應該清理名單
      • DELETE /_cluster/voting_config_exclusions
GET /_cluster/state?filter_path=metadata.cluster_coordination.voting_config_exclusions

今天的內容有點多,這邊做個總結

  1. 首先介紹了xpack不同層級的資安防護
    • 設定用戶密碼
    • node之間的通訊加密
    • client請求的通訊加密
  2. 以及幾種啟動多節點的方法
    • 自己設定好xpack然後本機啟動
    • 直接用預設設定的本機啟動(啟動前注意記憶體設定,啟動完後最好改個密碼)
    • 用docker啟動
  3. 最後我們介紹如何添加與刪除node
    • 用enrollment-token作為憑證加入
    • 依照不同刪除情境下有不同的作法
      • 如果是要一次大量刪除,透過將node添加進voting_config_exclusions的方法

參考資料
elastic stack security layer:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/configuring-stack-security.html
keystore:
https://www.elastic.co/guide/en/elasticsearch/reference/current/elasticsearch-keystore.html#add-string-to-keystore
minimal security:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html
basic security:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-basic-setup.html
https:
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-basic-setup-https.html
docker安裝ES:
https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html
添加或刪除node:
https://www.elastic.co/guide/en/elasticsearch/reference/current/add-elasticsearch-nodes.html#modules-discovery-removing-nodes


上一篇
【Day 24】由淺入深來探討Elasticsearch - Discovery and cluster formation(2)
下一篇
【Day 26】由淺入深來探討Elasticsearch - 探討ES寫操作原理
系列文
由淺入深來探討Elasticsearch,從基礎語法到底層相關原理30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言