在ROOK Ceph上使用Elastiecsearch和Kibana的Kubernetes监控#2
我想尝试使用ROOK Ceph的持久化存储来引入日志分析基础设施。在之前验证了ROOK Ceph的块存储并构建了一个使用永久性存储的应用程序Kubernetes监控#1 Promethus&Grafana on ROOK Ceph,用于构建度量监控。在这篇文章中,我想引入日志分析Elasticsearch和浏览器UI Kibana。
创建Elastiecsearch和示例应用的命名空间。
如果要部署和管理多个应用程序,例如Elastiecsearch和Guestbook到Kubernetes集群中,最好是创建一个专用的命名空间,并在其中运行。这是因为可以在命名空间中设置资源使用的上限。
在这里创建命名空间,并将其与上下文相关联,以便能够固定地访问命名空间。
kubectl create ns elasticsearch
kubectl create ns guestbook
kubectl config set-context es --namespace=elasticsearch --cluster=kubernetes --user=kubernetes-admin
kubectl config set-context gs --namespace=guestbook --cluster=kubernetes --user=kubernetes-admin
kubectl config get-contexts
在切换到es上下文时,即使省略了–namespace选项,也要确保elasticsearch有目标设置。
kubectl config use-context es
kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* es kubernetes kubernetes-admin elasticsearch
gs kubernetes kubernetes-admin guestbook
kubernetes-admin@kubernetes kubernetes kubernetes-admin
安装Elastiecsearch。
在Elasticsearch的文档中,最新版本8显示出来,但由于尚未发布正式版,所以我们会使用可以在互联网上获取的7.5.2版本。最近的快速安装指南中介绍的版本是6.8,但在这个版本下无法在最近流行的containerd引擎环境下运行。
如果在Helm中指定了Stable,搜索结果会出现问题,所以需要改变搜索参数。
helm search repo stable/elasticsearch
NAME CHART VERSION APP VERSION DESCRIPTION
stable/elasticsearch 1.32.2 6.8.2 Flexible and powerful open source, distributed ...
stable/elasticsearch-curator 2.1.3 5.7.6 A Helm chart for Elasticsearch Curator
stable/elasticsearch-exporter 2.2.0 1.1.0 Elasticsearch stats exporter for Prometheus
添加仓库并使用以下的elastic/elasticsearch进行设置。
helm repo add elastic https://helm.elastic.co
通过这个操作,现在可以使用显示在最顶端的版本7.5.2了。
helm search repo elasticsearch
NAME CHART VERSION APP VERSION DESCRIPTION
elastic/elasticsearch 7.5.2 7.5.2 Official Elastic helm chart for Elasticsearch
stable/elasticsearch 1.32.2 6.8.2 Flexible and powerful open source, distributed ...
stable/elasticsearch-curator 2.1.3 5.7.6 A Helm chart for Elasticsearch Curator
从文件中提取并编辑参数。
helm inspect values elastic/elasticsearch > elasticsearch-values.yaml
参数的修改部分,如下所示的 diff 结果只有一个地方。
tkr@luigi:~/sandbox-3/elasticsearch$ diff -c elasticsearch-values.yaml elasticsearch-values.yaml.org
*** elasticsearch-values.yaml 2020-01-26 21:25:07.434287399 +0900
--- elasticsearch-values.yaml.org 2020-02-10 16:45:43.829620681 +0900
***************
*** 82,88 ****
volumeClaimTemplate:
accessModes: [ "ReadWriteOnce" ]
- storageClassName: rook-ceph-block
resources:
requests:
storage: 30Gi
指定参数文件执行部署。由于先前提及的上下文已起作用,因此不需要指定命名空间。
helm install elasticsearch -f elasticsearch-values.yaml elastic/elasticsearch
NAME: elasticsearch
LAST DEPLOYED: Sun Jan 26 12:37:26 2020
NAMESPACE: elasticsearch
STATUS: deployed
REVISION: 1
NOTES:
1. Watch all cluster members come up.
$ kubectl get pods --namespace=elasticsearch -l app=elasticsearch-master -w
2. Test cluster health using Helm test.
$ helm test elasticsearch
在Helm的响应消息中指出,在所有的Pod都启动完成后,最好进行一次测试。这样,Elasticsearch的安装就完成了。到目前为止,PVC的保留量如下所示。
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
elasticsearch-master-elasticsearch-master-0 Bound pvc-40c22ed0-183a-439e-a139-2806260dc4f9 30Gi RWO rook-ceph-block 3m37s
elasticsearch-master-elasticsearch-master-1 Bound pvc-c1382774-007c-402a-bbd9-98de0cfe9256 30Gi RWO rook-ceph-block 3m37s
elasticsearch-master-elasticsearch-master-2 Bound pvc-bf45fd8b-74c6-4a06-9727-1485df232134 30Gi RWO rook-ceph-block 3m37s
Kibana的安装
接下来安装Kibana的用户界面。按照之前的方式,从Helm图表中生成参数文件。
helm inspect values elastic/kibana > kibana-values.yaml
将需要编辑的部分修改为以下差异,即将ClusterIP更改为NodePort,并分配nodePort号码。
diff -c kibana-values.yaml kibana-values.yaml.org
*** kibana-values.yaml 2020-01-26 21:53:56.023471404 +0900
--- kibana-values.yaml.org 2020-02-10 16:55:22.029673918 +0900
***************
*** 3,9 ****
elasticsearchURL: "" # "http://elasticsearch-master:9200"
elasticsearchHosts: "http://elasticsearch-master:9200"
-
replicas: 1
# Extra environment variables to append to this nodeGroup
--- 3,8 ----
***************
*** 78,86 ****
type: "Recreate"
service:
! type: NodePort
port: 5601
! nodePort: 31920
labels: {}
annotations: {}
# cloud.google.com/load-balancer-type: "Internal"
--- 77,85 ----
type: "Recreate"
service:
! type: ClusterIP
port: 5601
! nodePort: ""
labels: {}
annotations: {}
# cloud.google.com/load-balancer-type: "Internal"
使用编辑了参数的文件名作为输入,进行部署。
helm install kibana --namespace elasticsearch -f kibana-values.yaml elastic/kibana
请确认已按照更改所示,通过NodePort可访问。
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kibana-kibana NodePort 10.32.0.84 <none> 5601:31920/TCP 4m5s
当Kibana的Pod启动后,可以通过http://192.168.1.91:31920/app/kibana进行访问。
因为此时尚未进行日志发送器的设置,所以无法查看日志。
“Elasticsearch Beats是什么?”
Elasticsearch Beats是一个专门用于数据传输的工具,可以从数百台、数千台机器上将数据传输到Logstash和Elasticsearch。以下是根据不同用途设计的工具:
-
- Filebeat ログファイル転送
-
- Metricbeat メトリック
-
- Packetbeat ネットワークパケット
-
- Winlogbeat Windowsイベントログ
-
- Auditbeat 監査データ
-
- Heartbeat 稼働状態の監視
- Functionbeat サーバーレスシッパー
以前,Elasticsearch被描述为日志分析平台,但现在我们知道它还可以利用Beats的功能进行指标监控。
本文介绍如何设置Filebeat、Metricbeat和Auditbeat。
安装Beat
在安装Beat时,需要从GitHub上克隆并使用版本7.5.2。旧版本的Beat不支持容器引擎containerd,因此无法在旧的Beats上运行。如果使用OpenShift4,需要注意容器引擎将变为cri-o。
git clone -b 7.5 https://github.com/elastic/beats
cd beats/deploy/kubernetes
ls -al
合計 56
drwxrwxr-x 6 tkr tkr 4096 1月 26 17:28 .
drwxrwxr-x 4 tkr tkr 4096 1月 26 16:14 ..
drwxrwxr-x 2 tkr tkr 4096 1月 26 16:14 .travis
-rw-rw-r-- 1 tkr tkr 575 1月 26 16:14 Makefile
-rw-rw-r-- 1 tkr tkr 323 1月 26 16:14 README.md
drwxrwxr-x 2 tkr tkr 4096 1月 26 16:14 auditbeat
-rw-rw-r-- 1 tkr tkr 4286 1月 26 17:27 auditbeat-kubernetes.yaml
drwxrwxr-x 2 tkr tkr 4096 1月 26 16:14 filebeat
-rw-rw-r-- 1 tkr tkr 4003 1月 26 17:27 filebeat-kubernetes.yaml
drwxrwxr-x 2 tkr tkr 4096 1月 26 16:14 metricbeat
-rw-rw-r-- 1 tkr tkr 8744 1月 26 17:28 metricbeat-kubernetes.yaml
利用这个目录中的三个YAML文件进行安装后,可以完成安装,但还存在一个问题。这个问题是,即使安装了,也无法连接到Elasticsearch,导致无法正常运行。下面将解决这个问题的原因和对策。
击败的任务处理。
我们将以filebeat-kubernetes.yaml为例,查看其中的问题。其中设置了spec.hostNetwork=true。这表示
apiVersion: apps/v1
kind: DaemonSet
<中略>
spec:
serviceAccountName: filebeat
terminationGracePeriodSeconds: 30
hostNetwork: true <--- 注目
dnsPolicy: ClusterFirstWithHostNet
containers:
- name: filebeat
image: docker.elastic.co/beats/filebeat:7.5.2
args: [
"-c", "/etc/filebeat.yml",
"-e",
]
env:
- name: ELASTICSEARCH_HOST
value: elasticsearch-master.elasticsearch.svc.cluster.local
- name: ELASTICSEARCH_PORT
value: "9200"
由于日志收集目标包括节点,因此需要将hostNetwork设置为true。并且,为了从DNS名称进行地址解析,必须将设置为搜索”ClusterFirstWithHostNet”,该配置将在K8s集群内的DNS和主机网络DNS进行搜索。然而,在此环境中,无法通过外部DNS解析节点的地址。虽然不清楚是否直接导致此问题,但服务无法将其注册的DNS名称elasticsearch-master.elasticsearch.svc.cluster.local转换为IP地址。附上了API文档的翻译。
-
- hostNetwork:ブール値
-
- このポッドに要求されたホストネットワーキング。ホストのネットワーク名前空間を使用します。このオプションを設定する場合、使用するポートを指定する必要があります。デフォルトはfalseです。
-
- dnsPolicy: ストリング
- ポッドのDNSポリシーを設定します。デフォルトは「ClusterFirst」です。有効な値は「ClusterFirstWithHostNet」、「ClusterFirst」、「Default」または「None」です。DNSConfigで指定されたDNSパラメーターは、DNSPolicyで選択されたポリシーとマージされます。DNSオプションをhostNetworkとともに設定するには、DNSポリシーを明示的に「ClusterFirstWithHostNet」に指定する必要があります。
请参考以下网址了解有关Kubernetes API v1.17的核心PodSpec信息:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#podspec-v1-core
在此问题中,应该设置工作节点的外部DNS,并解析节点的DNS名称。但由于有点困难,所以可以采用简单的解决方案,即在清单中记录Elasticsearch服务的IP地址来解决这个问题。
每次部署时,都不想再次设置 IP 地址,但希望先实现最终目标后再思考。
获取Beat连接的IP地址并编辑清单文件
可以通过以下方式来确定Beat应该转发日志的服务器IP地址。
kubectl get svc elasticsearch-master
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch-master ClusterIP 10.32.0.3 <none> 9200/TCP,9300/TCP 61m
将这个 10.32.0.3 设置给前面提到的三个文件。需要编辑的位置是在第 73 行的 ELASTICSEARCH_HOST 的值。
72 env:
73 - name: ELASTICSEARCH_HOST
74 value: 10.32.0.3 ##elasticsearch-master.elasticsearch.svc.cluster.local
75 - name: ELASTICSEARCH_PORT
76 value: "9200"
77 - name: ELASTICSEARCH_USERNAME
78 value: <>
编辑后部署。
kubectl apply -f filebeat-kubernetes.yaml
kubectl get pod -n kube-system -l k8s-app=filebeat
NAME READY STATUS RESTARTS AGE
filebeat-8j998 1/1 Running 0 60s
filebeat-jszwk 1/1 Running 0 60s
filebeat-t422c 1/1 Running 0 60s
同样地,对metricbeat-kubernetes.yaml和auditbeat-kubernetes.yaml进行编辑并应用。
关于Beat的问题的具体细节
如果将ELASTICSEARCH_HOST设置为DNS名称作为发货地址,则会出现以下的lookup错误:没有此主机。
2020-01-26T04:08:33.186Z WARN transport/tcp.go:53 DNS lookup failure "elasticsearch-master.elasticsearch.svc.cluster.local": lookup elasticsearch-master.elasticsearch.svc.cluster.local: no such host
2020-01-26T04:08:34.335Z ERROR pipeline/output.go:100 Failed to connect to backoff(elasticsearch(http://elasticsearch-master.elasticsearch.svc.cluster.local:9200)): Get http://elasticsearch-master.elasticsearch.svc.cluster.local:9200: lookup elasticsearch-master.elasticsearch.svc.cluster.local: no such host
2020-01-26T04:08:34.335Z INFO pipeline/output.go:93 Attempting to reconnect to backoff(elasticsearch(http://elasticsearch-master.elasticsearch.svc.cluster.local:9200)) with 1 reconnect attempt(s)
然而,当使用DNS实用程序容器来确认地址时,确实可以看到已经注册并且可以解析地址。因此,可以确认Beat的Pod配置存在问题。
tkr@luigi:~/sandbox-rook/beats/deploy/kubernetes$ kubectl exec -ti -n default dnsutils -- nslookup 10.32.0.34
34.0.32.10.in-addr.arpa name = elasticsearch-master.elasticsearch.svc.cluster.local.
Kibana的配置和操作确认
点击排在左端最下方的齿轮图标后,可以看到数据正在从Beat传输。如果出现这种状态,则表示数据正在从每个Beat传输。如果没有显示,则请重新确认目标IP地址。
接下来,需要进行Discover的设置。点击左侧图标列顶部方位罗盘图标,将其设为Filebeat的首字母,并继续前进,将字段设置为@timestamp。
通过这个设置,可以获取日志的接收状态。
不仅可以显示日志,还可以显示指标信息。
总结
通过使用支持动态配置的 Rook Ceph 永久存储,我们能够部署日志分析基础设施 Elasticsearch 和 Kibana。Beat 工具非常实用,Filebeat 可以直接读取部署在工作节点上的容器文件系统,因此不需要单独为容器日志收集进行配置。Kibana 和 Elasticsearch 是非常实用的工具,我想重点写一篇关于这个部署的文章。
在尝试了这么多之后,最困难的事情是寻找适合的OSS组合来正确工作。此外,每个OSS项目都要异步推进项目并提供新版本和补丁,因此必须时刻保持警惕。另外,为了应对漏洞,还必须不断升级操作系统。ROOK是基于这个OSS堆栈构建的存储系统,虽然有建设成本低的优点,但也不能忽视维护运营的重要性。
安装Guestbook的附录
这个留言簿虽然并不使用永久存储,但可以作为日志输出测试应用程序使用。
kubectl config use-context gs
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-deployment.yaml
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-master-service.yaml
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-deployment.yaml
kubectl apply -f https://k8s.io/examples/application/guestbook/redis-slave-service.yaml
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
kubectl get svc,po
当所有的Pod都处于Running状态时,准备工作就完成了。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/frontend NodePort 10.32.0.188 <none> 80:32213/TCP 12s
service/redis-master ClusterIP 10.32.0.74 <none> 6379/TCP 50s
service/redis-slave ClusterIP 10.32.0.194 <none> 6379/TCP 32s
NAME READY STATUS RESTARTS AGE
pod/frontend-6cb7f8bd65-9kjhp 1/1 Running 0 22s
pod/frontend-6cb7f8bd65-wkrt5 1/1 Running 0 22s
pod/frontend-6cb7f8bd65-xt2mt 1/1 Running 0 22s
pod/redis-master-7db7f6579f-7pgjl 1/1 Running 0 60s
pod/redis-slave-7664787fbc-76zn9 1/1 Running 0 40s
pod/redis-slave-7664787fbc-qxg6x 1/1 Running 0 40s
以下是一个使用命令试验的例子,你可以通过使用上面的service/frontend的30000端口号和虚拟服务器的LAN侧IP地址来访问GuestBook网页,建议使用个人电脑的浏览器进行访问。
$ curl http://192.168.1.91:31178
<html ng-app="redis">
<head>
<title>Guestbook</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<以下省略>