konakona
Dream Afar.
konakona
使用docker-compose部署EFK服务
使用docker-compose部署EFK服务

前言

Kubernetes 集群本身不提供日志收集的解决方案,为了能够让Kubernetes排编日志,Kubernetes开发了Elasticsearch(简称es)附加组件来实现集群的日志管理。

本文将使用Elasticsearch、Fluentd、Kibana实现EFK组合。

分工如下:

  • Fluentd 负责 从kubernetes 搜集日志并发送到Elasticsearch;
  • Elasticsearch 是一个搜索引擎,负责存储日志并提供查询接口,没有web界面;
  • Kibana提供了一个Web GUI,用户可以浏览和搜索存储在Elasticsearch中的日志。
https://blog.img.crazyphper.com/2020/02/image.png

经典组合 ELK = Elasticsearch + Logstash + Kibana ,Logstash社区活跃度高,生态圈提供了大量插件支持。
Fluentd,整体性能不错,设计简洁,pipeline内数据传递可靠性高,较logstash插件支持相对少一些。

准备工作

我的部署方案是将Elasticsearch、Kibana使用docker安装在集群外部环境。

Fluentd部署在集群内部(必须如此),以DaemonSet方式为每一个节点运行一个 agent 来收集日志,然后提供给Elasticsearch接口。

Elasticsearch、Kibana和Fluentd可以通过YAML配置文件以附加组件的方式部署在kubernetes集群内部,详细见这篇文章,本文不采取这种方式。

环境预设

因为我master节点的80和443已经被其他老程序占用(历史原因),我需要将port改成其他的,再由nginx进行反代实现域名访问。

ELASTICSEARCH

version:7.6.0
host : es.domain.com
container name : es01
container port :8883 8445

Kibana

version.7.6.0
host : elk.domain.com
container name :kibana
CONTAINER port: 8884

Docker-compose文件

首先准备如下docker-compose.yaml文件为部署Elasticsearch和Kibana服务做准备:

version: "3"
services:
  es01: #请注意我的服务名称
    image: elasticsearch:7.6.0
    container_name: es01 #请注意我的容器名称
    environment:
      - cluster.name=suibianda #随便打
      - node.name=es01 #7.6.0必须有这个参数,即便你不使用Elasticsearch的集群
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.seed_hosts=es01
      - cluster.initial_master_nodes=es01
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
#       - data1:/usr/share/elasticsearch/data #我不想让Elasticsearch替我创建目录,因为不方便外部服务整体管理,所以下面我为Elasticsearch会使用到的目录进行了指派
      - "/data/elk/elasticsearch/data:/usr/share/elasticsearch/data"
      - "/data/elk/elasticsearch/config:/usr/share/elasticsearch/config"
      - "/data/elk/elasticsearch/logs:/usr/share/elasticsearch/logs"
    ports:
      - 8883:9200  # 请注意,我使用8883 对应容器内的9200,你可以改成80
      - 8445:9300  # 请注意,我使用8445 对应容器内的9300,你可以改成443
#     restart: "always"
    networks:
      - elastic   # 创建专有网络
  kibana: #服务名称
    image: kibana:7.6.0
    ports:
      - "8884:5601"  #暴露的端口信息和docker run -d -p 80:80 一样
#     restart: "always" #重启策略,能够使服务保持始终运行,生产环境推荐使用
    container_name: kibana #容器名称
    #volumes: # 我注释掉了是想告诉大家,完全可以依赖环境变量注入来实现等同于yml文件的配置效用
    #  - ./kibana.yml:/usr/share/kibana/config/kibana.yml
    environment:
      - ELASTICSEARCH_SSL_VERIFY=false
      - ELASTICSEARCH_URL="http://es01:9200" #容器对容器,所以写容器内的端口
      - ELASTICSEARCH_HOSTS="http://es01:9200"
      #- ELASTICSEARCH_USERNAME="*******" #如果你的es要求授权访问,在这里写入账号和密码
      #- ELASTICSEARCH_PASSWORD=*********
      - SERVER_NAME:"elk.domain.com"  # 填写kibana访问域名
    networks:
      - elastic
    depends_on:
      - es01
    
networks:
  elastic:
    driver: bridge

后续还会回来改这份yaml文件,但是现在我们要先成功部署Elasticsearch,进入容器内部使用一些命令来创建授权访问。如果你不需要限制访问,那么你可以在成功部署Elasticsearch后,直接跳去阅读Fluentd部分了。

执行docker-compose up -d es01单独启动Elasticsearch。

在服务器上使用curl localhost:8883查看服务是否正常运行。

https://blog.img.crazyphper.com/2020/02/image-3.png
有和一段json就说明部署成功

如果部署不成功,使用docker ps 看一下有没有kibana和es01,用docker logs es01或者docker logs kibana看一下报错原因。

由于任何人都可以访问到Elasticsearch并不安全,我们需要为其加一个授权账号和密码,在访问Elasticsearch时输入正确才可以使用。

使用X-Pack设置授权加密

接下来,针对7.6.0版本的ElasticSearch配置加密授权访问,下边的步骤是必不可少的,建议认真阅读下去。

ElasticSearch默认使用纯文本发送所有数据,包括密码。

https://blog.img.crazyphper.com/2020/02/image-7-727x600.png
交大泄漏

如果你想快速体验到EFK,你可以直接跳过这一步,前往Fluentd部署,就可以访问kibana的WEB地址获得你想要的了。待你体验完毕后想到了给Elasticsearch授权加密再回来补这一步也没差的。

X-Pack 是 ElasticSearch 的一个插件,这个插件将提供与ElasticSearch来往的安全性。通过安装这个插件,我们就可以对 ElasticSearch 的集群节点生成证书,配置服务访问密码,以及使用TLS来确保HTTP客户端与集群之间的通信是加密的。

强烈建议在HTTP层上启动TLS,但不是必须的。可以用lego脚本定期和自动的申请/更新免费证书。

由于我们容器化部署的ElasticSearch已经自带了x-pack部分,所以无需执行elasticsearch-plugin install x-pack安装的命令了。直接进入容器:

docker exec -ti es01 bash

进入容器后,前往工作目录下(即/usr/share/elasticsearch),为Elasticearch集群创建一个证书颁发机构。

使用elasticsearch-certutil命令输出一个默认名为elastic-stack-ca.p12的PKCS#12密钥存储库文件,它包含CA的公共证书和用于为每个节点签名证书的私钥。

cd /usr/share/elasticsearch
bin/elasticsearch-certutil ca
https://blog.img.crazyphper.com/2020/02/image-4-800x378.png
执行过程

执行exit退出容器,将p12文件移至/data/elk/elasticsearch/config文件夹。

docker cp es01:/usr/share/elasticsearch/elastic-stack-ca.p12 /data/elk/elasticsearch/config
sudo chmod -R 755 /data/elk/elasticsearch/config
docker-compose down

别忘了docker-compose down关掉服务,因为我们要改配置了。

应用证书

接下来,可以修改docker-compose.yaml的环境变量来使用加密授权,也可以修改config/elasticsearch.yml 来使用加密授权。环境变量的做法就是从入口上实现了elasticsearch.yml文件的配置作用,选其一即可。

方法一:修改docker-compose.yaml的方式

在elasticsearch部分的environment追加参数:

services:
  es01:
    image: elasticsearch:7.6.0
    container_name: es01
    environment:    
#下边为追加部分
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.keystore.type=PKCS12
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.keystore.path=elastic-stack-ca.p12
      - xpack.security.transport.ssl.truststore.path=elastic-stack-ca.p12
      - xpack.security.transport.ssl.truststore.type=PKCS12
      - xpack.security.enabled=true

执行docker-compose up -d elasticsearch,然后访问elasticsearch,发现成功出现授权要求。

https://blog.img.crazyphper.com/2020/02/image-5.png
但是这时我们还未设置账号和密码

方法二:修改elasticsearch.yaml的方式

cluster.name: "docker-cluster"
network.host: 0.0.0.0
#以下为追加部分
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.keystore.type: PKCS12
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: elastic-stack-ca.p12
xpack.security.transport.ssl.truststore.path: elastic-stack-ca.p12
xpack.security.transport.ssl.truststore.type: PKCS12
xpack.security.enabled: true

发现了吗?其实两边加的内容是一样的,所以很方便你按照自己的需求调整配置位置。不用两边都配!

设置授权访问的账号和密码

再次启动并进入容器docker exec -ti es01 bash,使用elasticsearch-setup-passwords为各个角色创建随机的密码:

bin/elasticsearch-setup-passwords auto

也可以使用密码设置来为每个角色设定密码:

bin/elasticsearch-setup-passwords interactive
https://blog.img.crazyphper.com/2020/02/image-6-800x204.png
interactive参数为每个角色设定密码

访问es.domain.com,输入user elastic的密码,成功获取正确json说明x-pack授权加密已经成功。

使Kibana应用帐号密码

在kibana部分的environment追加参数:

environment:
      - ELASTICSEARCH_USERNAME="kibana"
      - ELASTICSEARCH_PASSWORD="你刚刚生成的密码"

然后执行docker-compose up -d kibana 启动服务,等待几分钟,访问elk.domain.com,成功出现需要输入密码的界面说明配置成功。

https://blog.img.crazyphper.com/2020/02/image-11-554x600.png
输入elastic的密码进入

到这里,已经完成elasticsearch和kibana的全部部署工作。接下来,我们去处理日志收集的部分——fluentd。

kubernetes部署Fluentd

用官方准备的Fluentd YAML配置文件(ConfigMap x 1, DaemonSet x 1)来部署到集群内部。

wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/fluentd-es-configmap.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml

打开ConfigMap,修改最下面 output.conf中,@idhostport。而logstash_prefix

如果有加密授权部分还需要设置 user elasticpassword 你生成的密码

https://blog.img.crazyphper.com/2020/02/image-2-737x600.png

然后执行kubectl apply -f .进行部署。

检查一下Fluentd的运行情况:

kubectl get --namespace=kube-system pod
https://blog.img.crazyphper.com/2020/02/image-14.png

这就是正常启动啦,看看es.domain.com会出现你指定的logstash_prefix的日志数据。

https://blog.img.crazyphper.com/2020/02/image-15-800x414.png

到这里,我们的EFK部署之旅就结束了,感谢各位的阅读!


Fluentd pod 常见问题

301 Moved Permanently

https://blog.img.crazyphper.com/2020/02/image-12-800x97.png
unexpected error error_class=Elasticsearch::Transport::Transport::Errors::MovedPermanently error=”[301] 301 Moved Permanently

当遇到这个错误时,说明你使用了反代理服务(nginx),比如启用了TLS加密协议,还做了80跳443的代理设置,外部访问地址是TLS加密协议的。因此你需要修改ConfigMapoutput.conf部分:

      host es.domain.com
      scheme https
      ssl_verify true
      port 443

tlsv1 alert protocol version

https://blog.img.crazyphper.com/2020/02/image-13-800x33.png
[warn]: [es01] Could not communicate to Elasticsearch, resetting connection and trying again. SSL_connect returned=1 errno=0 state=error: tlsv1 alert protocol version (OpenSSL::SSL::SSLError)

当遇到这个错误时,说明你的https代理协议不允许使用TLS V1请求。

比如常用的nginx,修改成 ssl_protocols TLSv1 TLSv1.2;或者干脆去掉 ssl_protocols不指定也可以解决。

扩展阅读

Tweaking an EFK stack on Kubernetes

赞赏

团哥

文章作者

继续玩我的CODE,让别人说去。 低调,就是这么自信。

发表评论

textsms
account_circle
email

konakona

使用docker-compose部署EFK服务
前言 Kubernetes 集群本身不提供日志收集的解决方案,为了能够让Kubernetes排编日志,Kubernetes开发了Elasticsearch(简称es)附加组件来实现集群的日志管理。 本文将使用Elastics…
扫描二维码继续阅读
2020-02-26