Kubernetes日志分析利器:Elassandra部署使用指南
Elassandra是一個基于Apache Cassandra的Elasticsearch實現,有效結合了兩者的優勢,彌補了Elasticsearch的一些使用限制(單點故障、在線升級等)。結合Fluent-Bit以及Kibana,Elassandra為kubernetes集群日志分析提供了一個高效獨特的方案。
Elasticsearch升級
Elasticsearch采用主從分片架構設計:主節點管理映射修改;只有主分片支持寫操作,副本分片只能進行讀操作;當主分片故障時,主節點可以把副本分片升級為主分片。Cassandra的引入增強了Elassandra的可用性,弱化了主節點的單點控制作用,并且實現了多點寫操作。所有的節點都可以搜索請求,請求映射更新,并根據Cassandra的復制因子進行寫操作。
因此,Elassandra也可以更容易地通過kubernetes來管理,而且可以實現無宕機維護(滾動重啟升級)。除此以外,對集群進行水平擴容或收縮也很容易了,因為Elassandra完全兼容現有的Elasticsearch索引,我們只需要移動那些已經被重建的索引(重新索引)。Elassandra同時原生支持kubernetes集群的跨數據中心副本服務。
EFK部署
為了更好地讓Elassandra在Kubernetes中發揮作用,我們同樣搭配了一個EFK數據棧:在日志處理和轉發上,我們使用了Fluent-Bit,一個支持Elasticsearch后端的輕量日志處理引擎(當然也可以使用傳統的Fluentd或Filebeat);可視化面板方面則使用了普遍的Kibana。
基于EFK的Kubernetes集群結構圖
為使部署方便高效,我們使用了Helm的chart安裝包的方式,安裝源為Strapdata的Helm倉庫。
首先,我們建立了一個三節點集群,硬件上使用了SSD存儲,而軟件則使用了Azure的Kubenetes服務。集群搭建完成后,我們使用helm把Elassandra安裝到所有節點中,命令如下:
helm install --name \u0026quot;elassandra\u0026quot; --namespace default \\ --set image.repo=strapdata/elassandra \\ --set image.tag=6.2.3.10 \\ --set config.cluster_size=3 \\ --set persistence.storageClass=managed-premium \\ strapdata/elassandra安裝完成后,我們可以發現Elasticsearch服務和Cassandra服務已經暴露在kubernetes中了。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/cassandra ClusterIP 10.0.193.114 \u0026lt;none\u0026gt; 9042/TCP,9160/TCP 14hservice/elassandra ClusterIP None \u0026lt;none\u0026gt; 7199/TCP,7000/TCP,7001/TCP,9300/TCP,9042/TCP,9160/TCP,9200/TCP 14hservice/elasticsearch ClusterIP 10.0.75.121 \u0026lt;none\u0026gt;其次,部署Kibana。為保持兼容性,我們需要一個同Elasticsearch相同版本的安裝包,例如本文都使用了版本6.2.3。
helm install --namespace default --name my-kibana \\ --set image.tag=6.2.3 \\ --set service.externalPort=5601 \\ stable/kibana如果希望把Kibana服務暴露在公共IP上,我們在這里可以安裝一個kubernetes的入口代理—Traefik:
helm install --name traefik --namespace kube-system --set dashboard.domain=traefik-dashboard.aks1.strapdata.com stable/traefikhelm install --namespace $NAMESAPCE --name my-kibana --set image.tag=6.2.3 \\ --set service.externalPort=5601 \\ --set env.ELASTICSEARCH_URL=\u0026quot;http://elassandra-elasticsearch:9200\u0026quot; \\ --set ingress.enabled=true,ingress.hosts[0]=\u0026quot;kibana.${1:-aks1.strapdata.com}\u0026quot;,ingress.annotations.\u0026quot;kubernetes\\.io/ingress\\.class\u0026quot;=\u0026quot;traefik\u0026quot; \\ stable/kibana最后,我們需要使用一個特定的Elasticsearch索引模板來安裝Fluent-Bit,該模板加載了Elassandra相關的設置,從而可以優化日志存儲和搜索的性能。
helm install --name my-fluentbit --set trackOffsets=\u0026quot;true\u0026quot; \\--set backend.type=\u0026quot;es\u0026quot;,backend.es.host=\u0026quot;elassandra-elasticsearch.default.svc.cluster.local\u0026quot;,backend.es.time_key=\u0026quot;es_time\u0026quot;,backend.es.pipeline=\u0026quot;fluentbit\u0026quot; \\--set parsers.enabled=true,parsers.json[0].name=\u0026quot;docker\u0026quot;,parsers.json[0].timeKey=\u0026quot;time\u0026quot;,parsers.json[0].timeFormat=\u0026quot;%Y-%m-%dT%H:%M:%S.%L\u0026quot;,parsers.json[0].timeKeep=\u0026quot;Off\u0026quot; strapdata/fluent-bit到這里,我們就完成了對Elassandra、Fluent-Bit和Kibana的部署,Fluent-Bit開始源源不斷地把pod中的日志輸送到Elassandra集群。
接下來,我們再看一些針對Elassandra的優化設置:
Elassandra索引優化
Helm中Fluent-Bit的chart包為Elassandra提供了一個Elasticsearch索引模板,模板設置如下:
\u0026quot;settings\u0026quot;: { \u0026quot;index\u0026quot;: { \u0026quot;replication\u0026quot;: \u0026quot;DC1:2\u0026quot;, \u0026quot;table_options\u0026quot;: \u0026quot;compaction = {'compaction_window_size': '4', 'compaction_window_unit': 'HOURS', 'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'}\u0026quot;, \u0026quot;mapping\u0026quot;: { \u0026quot;total_fields\u0026quot;: { \u0026quot;limit\u0026quot;: \u0026quot;10000\u0026quot; } }, \u0026quot;refresh_interval\u0026quot;: \u0026quot;15s\u0026quot;, \u0026quot;drop_on_delete_index\u0026quot;: true, \u0026quot;index_insert_only\u0026quot;: true, \u0026quot;index_static_columns\u0026quot;: true, \u0026quot;search_strategy_class\u0026quot;: \u0026quot;RandomSearchStrategy\u0026quot; }Insert-Only模式
Elassandra中,Elasticsearc文檔的字段_source作為列項被存儲在Cassandra表中。在通過Elasticsearch索引API向Cassandra存儲層插入數據時,空字段會被默認賦值為null,從而避免覆蓋已有文檔。該插入操作同時產生了一些Cassandra墓碑,這些墓碑其實對很多不變日志記錄是沒有用處的,這時設置index.index_insert_only字段將會避免產生墓碑,從而達到優化Cassandra存儲的目的。
Drop on Delete Index設置
Elassandra采用Cassandra作為數據存儲層。一般情況下,Elassandra刪除一個索引并不會真正刪除底層Cassandra中的表和鍵空間。我們可以通過更改對index.drop_on_delete_index的設置,從而在刪除表中索引的同時也能自動刪除Cassandra中的表。
副本管理
Elassandra中,Cassandra取代Elasticsearch實現了數據副本管理。底層Cassandra的鍵空間副本映射保存了位置和副本數量。Elasticsearch模板中的index.replication字段定義了Cassandra的副本映射。本例中,我們在數據中心DC1中保存了兩個副本。
table_options字段
table_options字段定義Cassandra使用創建時間的表選項。因為日志記錄是不變的,我們在這里選擇使用Time Window Compactio策略來設計時間序列數據,當然我們也可以使用默認的TTL策略或壓縮策略(默認為LZ4)。
搜索策略類
在Elassandra中,調度節點會根據search_strategy_class定義的搜索策略將子請求分發到其他可用的節點中。默認的PrimaryFirstSearchStrategy策略會將子請求發送到所有的節點。我們在這里使用了RandomSearchStrategy,在數據中心能夠獲得一個結果的最小節點集。比如在我們采用六節點兩個副本要求的集群時,這種策略將只請求三個節點而不是六個,從而極大地減輕了集群的全局負載。
Elassandra映射優化
由于Elasticsearch使用了多值字段,Elassandra將所有類型為X的字段都保存到了一個Cassandra的列表X中。如果我們使用工具sstabledump查看產生的SSTables表,將得到如下由filebeat產生的Cassandra列:
{ \u0026quot;partition\u0026quot; : { \u0026quot;key\u0026quot; : [ \u0026quot;RL5Bp2cBWzCxo-DQnARL\u0026quot; ], \u0026quot;position\u0026quot; : 160123 }, \u0026quot;rows\u0026quot; : [ { \u0026quot;type\u0026quot; : \u0026quot;row\u0026quot;, \u0026quot;position\u0026quot; : 160691, \u0026quot;liveness_info\u0026quot; : { \u0026quot;tstamp\u0026quot; : \u0026quot;2018-12-13T11:09:14.378005Z\u0026quot; }, \u0026quot;cells\u0026quot; : [ { \u0026quot;name\u0026quot; : \u0026quot;es_time\u0026quot;, \u0026quot;deletion_info\u0026quot; : { \u0026quot;marked_deleted\u0026quot; : \u0026quot;2018-12-13T11:09:14.378004Z\u0026quot;, \u0026quot;local_delete_time\u0026quot; : \u0026quot;2018-12-13T11:09:14Z\u0026quot; } }, { \u0026quot;name\u0026quot; : \u0026quot;es_time\u0026quot;, \u0026quot;path\u0026quot; : [ \u0026quot;868796ae-fec7-11e8-aa29-7b1a7ab32955\u0026quot; ], \u0026quot;value\u0026quot; : \u0026quot;2018-12-13 11:08:42.265Z\u0026quot; }, { \u0026quot;name\u0026quot; : \u0026quot;kubernetes\u0026quot;, \u0026quot;deletion_info\u0026quot; : { \u0026quot;marked_deleted\u0026quot; : \u0026quot;2018-12-13T11:09:14.378004Z\u0026quot;, \u0026quot;local_delete_time\u0026quot; : \u0026quot;2018-12-13T11:09:14Z\u0026quot; } }, { \u0026quot;name\u0026quot; : \u0026quot;kubernetes\u0026quot;, \u0026quot;path\u0026quot; : [ \u0026quot;868796aa-fec7-11e8-aa29-7b1a7ab32955\u0026quot; ], \u0026quot;value\u0026quot; : {\u0026quot;container_name\u0026quot;: [\u0026quot;logs-generator\u0026quot;], \u0026quot;host\u0026quot;: [\u0026quot;aks-nodepool1-36080323-0\u0026quot;], \u0026quot;annotations\u0026quot;: null, \u0026quot;docker_id\u0026quot;: [\u0026quot;e38071228edf79584ef4eafdfb67c0144605a31730e71b02b3f6e1c8f27e0ea3\u0026quot;], \u0026quot;pod_id\u0026quot;: [\u0026quot;721a6540-fca4-11e8-8d8b-f6dcc5e73f85\u0026quot;], \u0026quot;pod_name\u0026quot;: [\u0026quot;logs-generator\u0026quot;], \u0026quot;namespace_name\u0026quot;: [\u0026quot;default\u0026quot;], \u0026quot;labels\u0026quot;: [{\u0026quot;app\u0026quot;: null, \u0026quot;controller-revision-hash\u0026quot;: null, \u0026quot;release\u0026quot;: null, \u0026quot;pod-template-generation\u0026quot;: null, \u0026quot;statefulset_kubernetes_io/pod-name\u0026quot;: null, \u0026quot;kubernetes_io/cluster-service\u0026quot;: null, \u0026quot;k8s-app\u0026quot;: null, \u0026quot;name\u0026quot;: null}]} }, { \u0026quot;name\u0026quot; : \u0026quot;log\u0026quot;, \u0026quot;deletion_info\u0026quot; : { \u0026quot;marked_deleted\u0026quot; : \u0026quot;2018-12-13T11:09:14.378004Z\u0026quot;, \u0026quot;local_delete_time\u0026quot; : \u0026quot;2018-12-13T11:09:14Z\u0026quot; } }, { \u0026quot;name\u0026quot; : \u0026quot;log\u0026quot;, \u0026quot;path\u0026quot; : [ \u0026quot;868796ab-fec7-11e8-aa29-7b1a7ab32955\u0026quot; ], \u0026quot;value\u0026quot; : \u0026quot;I1213 11:08:42.265287 6 logs_generator.go:67] 362287 PUT /api/v1/namespaces/ns/pods/s2qj 215\\u0026quot; }, { \u0026quot;name\u0026quot; : \u0026quot;stream\u0026quot;, \u0026quot;deletion_info\u0026quot; : { \u0026quot;marked_deleted\u0026quot; : \u0026quot;2018-12-13T11:09:14.378004Z\u0026quot;, \u0026quot;local_delete_time\u0026quot; : \u0026quot;2018-12-13T11:09:14Z\u0026quot; } }, { \u0026quot;name\u0026quot; : \u0026quot;stream\u0026quot;, \u0026quot;path\u0026quot; : [ \u0026quot;868796ac-fec7-11e8-aa29-7b1a7ab32955\u0026quot; ], \u0026quot;value\u0026quot; : \u0026quot;stderr\u0026quot; }, { \u0026quot;name\u0026quot; : \u0026quot;time\u0026quot;, \u0026quot;deletion_info\u0026quot; : { \u0026quot;marked_deleted\u0026quot; : \u0026quot;2018-12-13T11:09:14.378004Z\u0026quot;, \u0026quot;local_delete_time\u0026quot; : \u0026quot;2018-12-13T11:09:14Z\u0026quot; } }, { \u0026quot;name\u0026quot; : \u0026quot;time\u0026quot;, \u0026quot;path\u0026quot; : [ \u0026quot;868796ad-fec7-11e8-aa29-7b1a7ab32955\u0026quot; ], \u0026quot;value\u0026quot; : \u0026quot;2018-12-13 11:08:42.265Z\u0026quot; } ] } ] }我們可以看到,?Cassandra的集合類型(鏈表,集合,映射),產生了很多沒有用的負載。對此,Elassandra使用了新的屬性來擴展Elasticsearch映射,而這些屬性\u0026quot;cql_collection\u0026quot;:\u0026quot;singtelon\u0026quot;可以將Cassandra類型顯式地映射到單值字段。由于Fluent-Bit索引模板使用了這種單值字段映射屬性,Cassandra列存儲也變得更加輕量:
root@elassandra-0:/usr/share/cassandra# tools/bin/sstabledump /var/lib/cassandra/data/logstash_2018_12_17/flb_type-751e28a0022f11e9a83bbd84c8d6464a/mc-9-big-Data.db{ \u0026quot;partition\u0026quot; : { \u0026quot;key\u0026quot; : [ \u0026quot;nmWfvWcBHsJPeHipoGsM\u0026quot; ], \u0026quot;position\u0026quot; : 402735 }, \u0026quot;rows\u0026quot; : [ { \u0026quot;type\u0026quot; : \u0026quot;row\u0026quot;, \u0026quot;position\u0026quot; : 403179, \u0026quot;liveness_info\u0026quot; : { \u0026quot;tstamp\u0026quot; : \u0026quot;2018-12-17T19:23:34.412Z\u0026quot; }, \u0026quot;cells\u0026quot; : [ { \u0026quot;name\u0026quot; : \u0026quot;es_time\u0026quot;, \u0026quot;value\u0026quot; : \u0026quot;2018-12-17 19:23:33.603Z\u0026quot; }, { \u0026quot;name\u0026quot; : \u0026quot;kubernetes\u0026quot;, \u0026quot;value\u0026quot; : {\u0026quot;container_name\u0026quot;: \u0026quot;logs-generator\u0026quot;, \u0026quot;host\u0026quot;: \u0026quot;aks-nodepool1-36080323-0\u0026quot;, \u0026quot;docker_id\u0026quot;: \u0026quot;e33b2cda2ed7ac3bc5a6504cd79b6ea999137a11791d67fbb8b497fe06d8d700\u0026quot;, \u0026quot;pod_id\u0026quot;: \u0026quot;8ecacdcd-0229-11e9-8d8b-f6dcc5e73f85\u0026quot;, \u0026quot;pod_name\u0026quot;: \u0026quot;logs-generator\u0026quot;, \u0026quot;namespace_name\u0026quot;: \u0026quot;default\u0026quot;, \u0026quot;labels\u0026quot;: [{\u0026quot;app\u0026quot;: null, \u0026quot;component\u0026quot;: null, \u0026quot;controller-revision-hash\u0026quot;: null, \u0026quot;tier\u0026quot;: null, \u0026quot;pod-template-generation\u0026quot;: null, \u0026quot;name\u0026quot;: null, \u0026quot;pod-template-hash\u0026quot;: null, \u0026quot;version\u0026quot;: null, \u0026quot;k8s-app\u0026quot;: null, \u0026quot;kubernetes_io/cluster-service\u0026quot;: null, \u0026quot;release\u0026quot;: null, \u0026quot;statefulset_kubernetes_io/pod-name\u0026quot;: null, \u0026quot;run\u0026quot;: [\u0026quot;logs-generator\u0026quot;]}], \u0026quot;annotations\u0026quot;: null} }, { \u0026quot;name\u0026quot; : \u0026quot;log\u0026quot;, \u0026quot;value\u0026quot; : \u0026quot;I1217 19:23:33.600235 6 logs_generator.go:67] 2850 POST /api/v1/namespaces/ns/pods/65w 207\\u0026quot; }, { \u0026quot;name\u0026quot; : \u0026quot;stream\u0026quot;, \u0026quot;value\u0026quot; : \u0026quot;stderr\u0026quot; }, { \u0026quot;name\u0026quot; : \u0026quot;time\u0026quot;, \u0026quot;value\u0026quot; : \u0026quot;2018-12-17 19:23:33.603Z\u0026quot; } ] } ] }Elassandra存儲優化
Fluent-Bit為每一條日志記錄都添加了一些相關的kubernetes元數據,對于某一個容器來的日志記錄來說,所有的元數據都是相同的。對于這些日志記錄的元數據,由于Cassandra采用了寬列存儲,我們可以只存儲一次,這樣大大減小了SSTables的容量。下圖展示了Cassandra存儲中的Elasticsearch documents結構:
為實現上述結構,我們使用Elasticsearch管道改變了原始的JSON文檔,增加了一個時間戳(唯一的)來作為timeuuid(類型1UUID),并使用Cassandra復合主鍵構建了一個document_id字段,復合鍵包括使用Docker容器ID的分區鍵?,以及使用新timeuuid的集群鍵。
curl -H \u0026quot;Content-Type: application/json\u0026quot; -XPUT \u0026quot;http://elassandra-0:9200/_ingest/pipeline/fluentbit\u0026quot; -d'{ \u0026quot;description\u0026quot; : \u0026quot;fluentbit elassandra pipeline\u0026quot;, \u0026quot;processors\u0026quot; : [ { \u0026quot;timeuuid\u0026quot; : { \u0026quot;field\u0026quot;: \u0026quot;es_time\u0026quot;, \u0026quot;target_field\u0026quot;: \u0026quot;ts\u0026quot;, \u0026quot;formats\u0026quot; : [\u0026quot;ISO8601\u0026quot;], \u0026quot;timezone\u0026quot; : \u0026quot;Europe/Amsterdam\u0026quot; } }, { \u0026quot;set\u0026quot; : { \u0026quot;field\u0026quot;: \u0026quot;_id\u0026quot;, \u0026quot;value\u0026quot;: \u0026quot;[\\\u0026quot;{{kubernetes.docker_id}}\\\u0026quot;,\\\u0026quot;{{ts}}\\\u0026quot;]\u0026quot; } } ]}'這樣,我們可以將下面的映射屬性添加到我們的Fluent-bit Elasticsearch模板中:
- 分區鍵列中字段賦值:cql_partition_key:true,?cql_primary_key_order:0
- 集群鍵列中字段賦值:cql_primary_key_order:1,cql_type:timeuuid
- Kubernetes元數據列中字段賦值:??cql_static_column:true
我們同時添加了索引設置:index.index_static_columns:true?,用來索引Cassandra靜態列和所有的行。
在清除現存的索引、重新部署新的Elasticsearch管道和模板之后,SSTables只需要每天為每個容器保存一個寬列日志存儲。這樣,我們大大優化了存儲性能,并且Kubernetes元數據只需要每天保存一個Docker容器即可。同時由于timeuuid列可以被Elasticsearch當作日期使用,Cassandra集群鍵清除了一些時間字段,設置是時間戳字段,例如es_time和time等。
{ \u0026quot;partition\u0026quot; : { \u0026quot;key\u0026quot; : [ \u0026quot;f9f237c2d64dd8b92130fd34f567b162f0ae1972e7afabee9151539ba31ccadd\u0026quot; ], \u0026quot;position\u0026quot; : 2800 }, \u0026quot;rows\u0026quot; : [ { \u0026quot;type\u0026quot; : \u0026quot;static_block\u0026quot;, \u0026quot;position\u0026quot; : 3326, \u0026quot;cells\u0026quot; : [ { \u0026quot;name\u0026quot; : \u0026quot;kubernetes\u0026quot;, \u0026quot;value\u0026quot; : {\u0026quot;container_name\u0026quot;: \u0026quot;put-template\u0026quot;, \u0026quot;host\u0026quot;: \u0026quot;aks-nodepool1-36080323-0\u0026quot;, \u0026quot;pod_id\u0026quot;: \u0026quot;e24f2521-1256-11e9-8fe6-de1ce27ac649\u0026quot;, \u0026quot;pod_name\u0026quot;: \u0026quot;fluent-bit-sc6m6\u0026quot;, \u0026quot;namespace_name\u0026quot;: \u0026quot;default\u0026quot;, \u0026quot;labels\u0026quot;: [{\u0026quot;app\u0026quot;: \u0026quot;my-fluentbit-fluent-bit\u0026quot;, \u0026quot;component\u0026quot;: null, \u0026quot;controller-revision-hash\u0026quot;: \u0026quot;3156758786\u0026quot;, \u0026quot;tier\u0026quot;: null, \u0026quot;pod-template-generation\u0026quot;: \u0026quot;1\u0026quot;, \u0026quot;name\u0026quot;: null, \u0026quot;pod-template-hash\u0026quot;: null, \u0026quot;version\u0026quot;: null, \u0026quot;k8s-app\u0026quot;: null, \u0026quot;kubernetes_io/cluster-service\u0026quot;: null, \u0026quot;release\u0026quot;: [\u0026quot;my-fluentbit\u0026quot;], \u0026quot;statefulset_kubernetes_io/pod-name\u0026quot;: null}], \u0026quot;annotations\u0026quot;: [{\u0026quot;checksum/config\u0026quot;: [\u0026quot;3375211361605629fc5a1f970e1fce0ce2fabbcb08ef4631acdc4bd2ac41fd7b\u0026quot;], \u0026quot;scheduler_alpha_kubernetes_io/critical-pod\u0026quot;: null, \u0026quot;prometheus_io/port\u0026quot;: null, \u0026quot;prometheus_io/scrape\u0026quot;: null}]}, \u0026quot;tstamp\u0026quot; : \u0026quot;2019-01-07T08:33:35.968Z\u0026quot; } ] }, { \u0026quot;type\u0026quot; : \u0026quot;row\u0026quot;, \u0026quot;position\u0026quot; : 3326, \u0026quot;clustering\u0026quot; : [ \u0026quot;e4375630-1256-11e9-a990-c3ec4d724241\u0026quot; ], \u0026quot;liveness_info\u0026quot; : { \u0026quot;tstamp\u0026quot; : \u0026quot;2019-01-07T08:33:35.954Z\u0026quot; }, \u0026quot;cells\u0026quot; : [ { \u0026quot;name\u0026quot; : \u0026quot;log\u0026quot;, \u0026quot;value\u0026quot; : \u0026quot; % Total % Received % Xferd Average Speed Time Time Time Current\\u0026quot; }, { \u0026quot;name\u0026quot; : \u0026quot;stream\u0026quot;, \u0026quot;value\u0026quot; : \u0026quot;stderr\u0026quot; } ] }, { \u0026quot;type\u0026quot; : \u0026quot;row\u0026quot;, \u0026quot;position\u0026quot; : 3326, \u0026quot;clustering\u0026quot; : [ \u0026quot;e4375630-1256-11e9-0566-b0312df0dcfc\u0026quot; ], \u0026quot;liveness_info\u0026quot; : { \u0026quot;tstamp\u0026quot; : \u0026quot;2019-01-07T08:33:35.964Z\u0026quot; }, \u0026quot;cells\u0026quot; : [ { \u0026quot;name\u0026quot; : \u0026quot;log\u0026quot;, \u0026quot;value\u0026quot; : \u0026quot; Dload Upload Total Spent Left Speed\\u0026quot; }, { \u0026quot;name\u0026quot; : \u0026quot;stream\u0026quot;, \u0026quot;value\u0026quot; : \u0026quot;stderr\u0026quot; } ] }我們可以在這里使用Kibana來創建面板,分析日志。
可用性測試
最后,我們通過實例來驗證一下Elassandra的可用性。
首先,創建一個日志產生器,輸出實驗所需要的日志記錄。
for i in {1..20}; do kubectl run logs-generator${i} --generator=run-pod/v1 --image=k8s.gcr.io/logs-generator:v0.1.1 \\--restart=Never --env \u0026quot;LOGS_GENERATOR_LINES_TOTAL=50000\u0026quot; --env \u0026quot;LOGS_GENERATOR_DURATION=3m\u0026quot;; done其次,我們強制關閉一個Elassandra pod,人為制造一個單點故障,然后由Kubernetes控制器自動重啟。
$kubectl delete pod/elassandra-1 pod \u0026quot;elassandra-1\u0026quot; deleted這種情況下,如果Cassandra只有一個副本,關閉主節點將會產生寫錯誤。
[2019/01/10 16:46:09] [ warn] [out_es] Elasticsearch error{\u0026quot;took\u0026quot;:3,\u0026quot;ingest_took\u0026quot;:2,\u0026quot;errors\u0026quot;:true,\u0026quot;items\u0026quot;:[{\u0026quot;index\u0026quot;:{\u0026quot;_index\u0026quot;:\u0026quot;logstash-2019.01.10\u0026quot;,\u0026quot;_type\u0026quot;:\u0026quot;flb_type\u0026quot;,\u0026quot;_id\u0026quot;:\u0026quot;[\\\u0026quot;c0e45980637031ed19386d8a2b3fa736597057eea46917b8c28b73ba640e3cc3\\\u0026quot;,\\\u0026quot;25c13480-14f6-11e9-2b53-a734ca6c6447\\\u0026quot;]\u0026quot;,\u0026quot;status\u0026quot;:500,\u0026quot;error\u0026quot;:{\u0026quot;type\u0026quot;:\u0026quot;write_failure_exception\u0026quot;,\u0026quot;reason\u0026quot;:\u0026quot;Operation failed - received 0 responses and 1 failures\u0026quot;}}},{\u0026quot;index\u0026quot;:{\u0026quot;_index\u0026quot;:\u0026quot;logstash-2019.01.10\u0026quot;,\u0026quot;_type\u0026quot;:\u0026quot;flb_type\u0026quot;,\u0026quot;_id\u0026quot;:\u0026quot;[\\\u0026quot;c0e45980637031ed19386d8a2b3fa736597057eea46917b8c28b73ba640e3cc3\\\u0026quot;,\\\u0026quot;372b3680-14f6-11e9-d3d8-e1397bcf3034\\\u0026quot;]\u0026quot;,\u0026quot;status\u0026quot;:500,\u0026quot;error\u0026quot;:{\u0026quot;type\u0026quot;:\u0026quot;write_failure_exception\u0026quot;,\u0026quot;reason\u0026quot;:\u0026quot;Operation failed - received 0 responses and 1 failures\u0026quot;}}},{\u0026quot;index\u0026quot;:{\u0026quot;_index\u0026quot;:\u0026quot;logstash-2019.01.10\u0026quot;,\u0026quot;_type\u0026quot;:\u0026quot;flb_type\u0026quot;,\u0026quot;_id\u0026quot;:\u0026quot;[\\\u0026quot;c0e45980637031ed19386d8a2b3fa736597057eea46917b8c28b73ba640e3cc3\\\u0026quot;,\\\u0026quot;41a8c280-14f6-11e9-bc51-b90088b4aa65\\\u0026quot;]\u0026quot;,\u0026quot;status\u0026quot;:500,\u0026quot;error\u0026quot;:{\u0026quot;type\u0026quot;:\u0026quot;write_failure_exception\u0026quot;,\u0026quot;reason\u0026quot;:\u0026quot;Operation failed - received 0 responses and 1 failur然后,我們為Logstash索引創建兩個Cassandra副本,并重復上述測試。
kubectl exec -it elassandra-0 -- cqlshConnected to elassandra at 127.0.0.1:9042.[cqlsh 5.0.1 | Cassandra 3.11.3.5 | CQL spec 3.4.4 | Native protocol v4]Use HELP for help.cqlsh\u0026gt; ALTER KEYSPACE logstash_2019_01_10 WITH replication = {'class': 'NetworkTopologyStrategy','DC1':'2'};雖然在測試中Fluent-Bit提示器顯示有一些連接中斷錯誤,但它仍然將數據保存到了Elassandra。
[2019/01/10 16:57:39] [error] [http_client] broken connection to elassandra-elasticsearch.default.svc.cluster.local:9200 ?[2019/01/10 16:57:39] [ warn] [out_es] http_do=-1[2019/01/10 16:57:39] [error] [http_client] broken connection to elassandra-elasticsearch.default.svc.cluster.local:9200 ?[2019/01/10 16:57:39] [ warn] [out_es] http_do=-1Cassandra使用了多主節點架構,即便重啟一個節點,我們仍然可以通過Elasticsearch的API在其他節點上進行寫操作。如果丟失了一個節點,Elasticsearch指示器將變為黃色,但搜索功能仍能繼續使用。
health status index uuid pri rep docs.count docs.deleted store.size pri.store.sizeyellow open logstash-2019.01.10 p01ngidBRDSVsi99NupG5g 3 1 227478 0 88.3mb 88.3mbyellow open .kibana 68N_Dsk0SoOG9jHElafDUw 3 1 3 0 15.8kb 15.8kb節點重啟后,Elasticsearch指示器將重新變為綠色,Cassandra節點2和節點3會將hint handoff發送到節點1,以便恢復丟失的日志記錄。
結語
Elassandra的出現為Kubernetes中的日志處理增加了很多使用場景,如上文所示:通過相應的設置,你可以使用Elasticsearch的管道處理器來更改或優化Cassandra存儲,即便我們不使用Elasticsearch的索引功能(在Elasticsearch映射中設置index=no,如此將只獲得底層Cassandra表中的數據);在維護Elassandra集群時,我們也可以在不關機的情況下實現滾動升級;亦或者在不用重新索引的情況下輕松實現水平擴展。
當然,Elassandra也終于開始為混合云中的跨Kubernetes集群提供副本支持,詳情將在其他文章中展開。
英文原文地址:https://dzone.com/articles/kubernetes-logs-with-elassandra?utm_medium=feed\u0026amp;utm_source=feedpress.me\u0026amp;utm_campaign=Feed:%20dzone
總結
以上是生活随笔為你收集整理的Kubernetes日志分析利器:Elassandra部署使用指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP 项目中单独使用 Laravel
- 下一篇: python实例(一)