前言
Kubernetes 集群本身不提供日志收集的解决方案,为了能够让Kubernetes排编日志,Kubernetes开发了Elasticsearch(简称es)附加组件来实现集群的日志管理。
本文将使用Elasticsearch、Fluentd、Kibana实现EFK组合。
分工如下:
- Fluentd 负责 从kubernetes 搜集日志并发送到Elasticsearch;
- Elasticsearch 是一个搜索引擎,负责存储日志并提供查询接口,没有web界面;
- Kibana提供了一个Web GUI,用户可以浏览和搜索存储在Elasticsearch中的日志。
经典组合 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
查看服务是否正常运行。
如果部署不成功,使用docker ps
看一下有没有kibana和es01,用docker logs es01
或者docker logs kibana
看一下报错原因。
由于任何人都可以访问到Elasticsearch并不安全,我们需要为其加一个授权账号和密码,在访问Elasticsearch时输入正确才可以使用。
使用X-Pack设置授权加密
接下来,针对7.6.0版本的ElasticSearch配置加密授权访问,下边的步骤是必不可少的,建议认真阅读下去。
ElasticSearch默认使用纯文本发送所有数据,包括密码。
如果你想快速体验到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
执行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,发现成功出现授权要求。
方法二:修改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
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
,成功出现需要输入密码的界面说明配置成功。
到这里,已经完成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
中,@id
、host
和port
。而logstash_prefix
。
如果有加密授权部分还需要设置 user elastic
、password 你生成的密码
。
然后执行kubectl apply -f .
进行部署。
检查一下Fluentd的运行情况:
kubectl get --namespace=kube-system pod
这就是正常启动啦,看看es.domain.com
会出现你指定的logstash_prefix
的日志数据。
到这里,我们的EFK部署之旅就结束了,感谢各位的阅读!
Fluentd pod 常见问题
301 Moved Permanently
当遇到这个错误时,说明你使用了反代理服务(nginx),比如启用了TLS加密协议,还做了80跳443的代理设置,外部访问地址是TLS加密协议的。因此你需要修改ConfigMap
的output.conf
部分:
host es.domain.com
scheme https
ssl_verify true
port 443
tlsv1 alert protocol version
当遇到这个错误时,说明你的https代理协议不允许使用TLS V1请求。
比如常用的nginx,修改成 ssl_protocols TLSv1 TLSv1.2;
或者干脆去掉 ssl_protocols
不指定也可以解决。
发表回复