栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

ElasticSearch Kubernetes

ElasticSearch Kubernetes

文章目录
    • 架构选型
      • 业务容器直连
      • Node DaemonSet
      • sidecar
    • 部署模型
      • 查看helm的渲染结果
      • 部署模型
    • 部署ELK stack
      • 部署elk & kibana
        • 注意点
          • 资源限制
          • pod反亲和性策略
          • 持久化PV
          • NodePort端口开放
      • 部署NFS Persistent Volume
      • 部署filebeat
    • 概念验证
    • 总结

默认情况下,如果Pod在节点被删除,日志就被删除了。因此,为了保留日志,我们需要调研一个日志集中存储方案。

架构选型

根据Kubernetes官方文档:https://kubernetes.io/docs/concepts/cluster-administration/logging/

架构方案大致是分成三种

  • 业务容器直连
  • Node DaemonSet
  • Sidecar
业务容器直连

集成日志中间件的SDK,由业务容器直接发送日志到elasticsearch中间件。

  • 缺点:
    中间件和日志中间件耦合性比较强,还需要处理网络,命名空间等各种kubernetes相关信息。因此是不推荐的。
Node DaemonSet

DaemonSet会在每个Node节点运行一个agent。由filebeat agent监控docker容器日志,发送到elastcsearch.

本文实现使用的是这种方案。

sidecar

app-container将日志写入到文件,streaming container 作为sidecar容器,处理日志内容,打印到stdout和stderr. 当然,相对于filebeat DaemonSet Pod而言,一切都没有变。

这种方案资源占用虽然较多,不过可以提供复杂日志信息过滤能力,更好的租户隔离性。

基于Kubernetes Volume这种方式可以很轻松的实现,Volume和Pod具有相同的声明周期,用于临时处于同一Pod的容器共享存储。

如下声明了一个Pod,有两个容器,分别是count(模拟业务容器)和watcher(模拟sidecar)容器,创建了一个Volume用于容器间共享存储。

count不在将日志写入标准输出流,而是写到日志文件中。
watcher将处理日志文件,输出到stdout和stderr

apiVersion: v1
kind: Pod
metadata:
  name: sleeper
spec:
  containers:
  - name: count
    image: busybox
    args: [/bin/sh, -c,
            'i=0; while true; do echo "$i: $(date) we are good" >> /cache/hello.log ; i=$((i+1)); sleep 1; done']
    volumeMounts:
    - mountPath: /cache
      name: cache-volume

  - name: watcher
    image: busybox 
    args: [/bin/sh, -c,
            'tail -f /cache/hello.log']
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  # 共享存储Volume
  volumes: 
  - name: cache-volume
    emptyDir: {}
部署模型 查看helm的渲染结果

helm chart是一种模板语法,你可以通过

# elasticsearch 为部署名
helm get manifest elasticsearch 

查看helm的资源文件清单。

部署模型

elk的部署模型为一个3实例的高可用集群。

如下所示:

集群中每个Pod的身份是不一样的,有主从角色,所以要使用到kubernetes的StatefulSet和Headless Service.

helm chart的渲染结果同时有两个Service,一个是正常的,一个是headless类型的。

# Source: elasticsearch/templates/service.yaml
kind: Service
apiVersion: v1
metadata:
  name: elasticsearch-master
spec:
  type: NodePort
  selector:
    release: "elk"
    chart: "elasticsearch"
    app: "elasticsearch-master"
  ports:
  - name: http
    protocol: TCP
    port: 9200
    nodePort: 32000
  - name: transport
    protocol: TCP
    port: 9300
---
# Source: elasticsearch/templates/service.yaml
kind: Service
apiVersion: v1
metadata:
  name: elasticsearch-master-headless
spec:
  clusterIP: None # This is needed for statefulset hostnames like elasticsearch-0 to resolve
  # Create endpoints also if the related pod isn't ready
  publishNotReadyAddresses: true
  selector:
    app: "elasticsearch-master"
  ports:
  - name: http
    port: 9200
  - name: transport
    port: 9300

正常的Service通常都有一个ClusterIP, 服务通过DNS名 ${service name} 访问时,会解析为ClusterIP。但是Headless Service被访问时,会被解析为Pod的IP。

因此elk的配置发现节点的配置时,选择的是headless 服务。

          - name: discovery.seed_hosts
            value: "elasticsearch-master-headless"  # 会被解析为多个用","分隔的ip

当filebeat和kibana访问elasticsearch时,使用的是普通Service。

部署ELK stack

下面以Node DaemonSet方式实现集中化日志采集。filebeat作为logging agent, elasticsearch作为logging backend.最后通过Kibana查看日志。

基于以下组件实现kubernetes环境的日志采集,做一个快速的概念验证:

组件version
elasticsearch7.16.2
kibana7.16.2
filebeat7.16.2

ELK技术栈是典型的有状态应用,本文基于开源项目:https://github.com/elastic/helm-charts.git

部署elk & kibana

请安装helm v3

helm repo add elastic https://helm.elastic.co
helm install elasticsearch elastic/elasticsearch
helm install kibana elastic/kibana
注意点

需要helm基础知识

需要修改chart, chart开放了values.yaml用于参数微调。因此下面的配置都在value.yaml下调整。

helm install下载完成之后,chart在用户目录下,以tgz文件格式存在:

# ls /root/.cache/helm/repository/
elastic-charts.txt        elastic-index.yaml        elasticsearch-7.16.2.tgz  kibana-7.16.2.tgz   

将tgz文件解压,需要调整values.yaml的参数,重新upgrade一遍。

tar xf  elasticsearch-7.16.2.tgz
# 修改完values.yaml
# elk 部署名   elasticsearch/ tgz解压形成的文件
helm install elk elasticsearch/
资源限制

我的机器是8G的,无法运行三实例elasticsearch和kibana。因此可以调整副本数量为1

replicas: 1
pod反亲和性策略

默认chart使用了部署了3个elk实例组成高可用集群,使用pod反亲和性策略,elk集群节点不能处于同一kubernetes节点。

可以修改values.yaml:

# Hard means that by default pods will only be scheduled if there are enough nodes for them
# and that they will never end up on the same node. Setting this to soft will do this "best effort"
antiAffinity: "soft"
持久化PV
  • 使用NFS进行持久化PV供应,需要调整NFS文件夹权限
# cat /etc/exports
/data/share *(rw,sync,insecure,no_subtree_check,no_root_squash)
  • 修改共享文件夹的权限:

如果不修改共享文件夹的权限,会碰到elasticsearch无法访问持久化卷的情况,报错如下:

How to fix ElasticSearch docker AccessDeniedException[/usr/share/elasticsearch/data/nodes];”,

解决方案:

sudo chown -R 1000:1000 [directory]
  • 原因

根据Kubernetes Pod Security Context:,容器可以设置以某些用户身份运行,比如elk就是以用户ID 1000运行的

  securityContext:
    fsGroup: 1000
    runAsUser: 1000
  automountServiceAccountToken: true

所以将pv的用户权限全部改为UID 1000用户所有就没问题了。

NodePort端口开放
  • elk
service:
  enabled: true
  labels: {}
  labelsHeadless: {}
  type: NodePort # 修改为NodePort方式
  nodePort: "32000" # 指定具体的NodePort端口
  • kibana
service:
  type: NodePort
  loadBalancerIP: ""
  port: 5601
  nodePort: "30090"
部署NFS Persistent Volume

将以下内容保存为pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity:
    storage: 60Gi
  accessModes:
    - ReadWriteonce
  nfs:
    server: 192.168.10.2
    path: "/data/share"

创建PV

kubectl apply -f pv.yaml
部署filebeat
kubectl apply -f https://raw.githubusercontent.com/elastic/beats/7.16/deploy/kubernetes/filebeat-kubernetes.yaml

默认filebeat会部署在kube-system命名空间里,你可以修改filebeat连接elastic的地址为${NODE_IP}:${nodePort}

        env:
        - name: ELASTICSEARCH_HOST
          value: elasticsearch 
        - name: ELASTICSEARCH_PORT
          value: "9200"
概念验证

部署一个busybox Pod,定期输出日志,在kibana里查看日志。

busybox.yaml 在第三种方案的样例里


可以通过namespace, pod名,deployment名字筛选查看日志了。

总结

将elk部署至kubernetes需要考虑高可用性,有状态服务,持久化存储,kubernetes的RBAC权限等问题。部署的最佳实践当然是使用开源的helm chart,然后在开发环境先适用一段时间,根据实际环境进行优化。

日志集中化处理的主要优点是,在kubernetes这种动态环境中,你可以看到消亡的Pod日志,做崩溃原因分析。这是kubectl logs 做不到的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/679611.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号