Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch
、Fluentd
和 Kibana
(EFK)技术栈,也是官方现在比较推荐的一种方案。
Elasticsearch
是一个实时的、分布式的可扩展的搜索引擎,允许进行全文、结构化搜索,它通常用于索引和搜索大量日志数据,也可用于搜索许多不同类型的文档。
Elasticsearch
通常与 Kibana
一起部署,Kibana
是 Elasticsearch
的一个功能强大的数据可视化 Dashboard,Kibana
允许你通过 web 界面来浏览Elasticsearch
日志数据。
Fluentd
是一个流行的开源数据收集器,我们将在 Kubernetes 集群节点上安装 Fluentd
,通过获取容器日志文件、过滤和转换日志数据,然后将数据传递到 Elasticsearch 集群,在该集群中对其进行索引和存储。
我们先来配置启动一个可扩展的 Elasticsearch 集群,然后在 Kubernetes 集群中创建一个 Kibana 应用,最后通过 DaemonSet 来运行 Fluentd,以便它在每个 Kubernetes 工作节点上都可以运行一个 Pod。
安装 Elasticsearch 集群
先创建一个命名空间,我们将在其中安装所有日志相关的资源对象。
1
| kubectl create ns kube-logging
|
环境准备
ElasticSearch
安装有最低安装要求,如果安装后 Pod 无法正常启动,请检查是否符合最低要求的配置,要求如下:
节点 | CPU最低要求 | 内存最低要求 |
---|
elasticsearch-master | 核心数>2 | 内存>2G |
elasticsearch-data | 核心数>1 | 内存>2G |
elasticsearch-client | 核心数>1 | 内存>2G |
集群节点信息
集群 | 节点类型 | 副本数目 | 存储大小 | 网络模式 | 描述 |
---|
elasticsearch | master | 3 | 5Gi | ClusterIP | 主节点 |
elasticsearch-data | data | 3 | 50Gi | ClusterIP | 数据节点 |
elasticsearch-client | client | 2 | 无 | NodePort | 负责处理用户请求 |
建议使用 StorageClass
来做持久化存储,当然如果你是线上环境建议使用 Local PV 或者 Ceph RBD 之类的存储来持久化 Elasticsearch 的数据。
由于 ElasticSearch 7.x 版本默认安装了 X-Pack 插件,并且部分功能免费,需要我们配置一些安全证书文件。
准备生成证书文件
注意:由于我们采用的是containerd
所以使用nerdctl
来运行一个容器
1 2 3 4 5 6 7 8 9 10
| mkdir -p elastic-certs nerdctl run --name elastic-certs -v elastic-certs:/app -it -w /app elasticsearch:7.17.3 /bin/sh -c \ "elasticsearch-certutil ca --out /app/elastic-stack-ca.p12 --pass '' && \ elasticsearch-certutil cert --name security-master --dns \ security-master --ca /app/elastic-stack-ca.p12 --pass '' --ca-pass '' --out /app/elastic-certificates.p12"
cd /var/lib/nerdctl/1935db59/volumes/default/elastic-certs/_data/
mv * /root/elastic-certs/ cd /root/elastic-certs/ && openssl pkcs12 -nodes -passin pass:'' -in elastic-certificates.p12 -out elastic-certificate.pem
|
- 添加证书到
kubernetes
1 2 3
| kubectl create secret -n kube-logging generic elastic-certs --from-file=elastic-certificates.p12
kubectl create secret -n kube-logging generic elastic-auth --from-literal=username=elastic --from-literal=password=elastic-master
|
准备安装Elastic集群
- 采用
Helm
的方式来添加elasticsearch
仓库
1 2
| helm repo add elastic https://helm.elastic.co helm repo update
|
ElaticSearch 安装需要安装三次,分别安装 Master、Data、Client 节点,Master 节点负责集群间的管理工作;Data 节点负责存储数据;Client 节点负责代理 ElasticSearch Cluster 集群,负载均衡。
2. 拉取elasticsearch
1 2
| helm pull elastic/elasticsearch --untar --version 7.17.3 cd elasticsearch/
|
在Chart目录下创建对应节点节点的values
文件
以下是master-value.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| clusterName: "elasticsearch"
nodeGroup: "master"
roles: master: "true" ingest: "false" data: "false"
image: "docker.elastic.co/elasticsearch/elasticsearch" imageTag: "7.17.3" imagePullPolicy: "IfNotPresent"
replicas: 3
esJavaOpts: "-Xmx1g -Xms1g" resources: requests: cpu: "2000m" memory: "2Gi" limits: cpu: "2000m" memory: "2Gi"
persistence: enabled: true
volumeClaimTemplate: storageClassName: managed-nfs-storage accessModes: ['ReadWriteOnce'] resources: requests: storage: 5Gi
protocol: http
secretMounts: - name: elastic-certs secretName: elastic-certs path: /usr/share/elasticsearch/config/certs defaultMode: 0755
esConfig: elasticsearch.yml: | xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 # xpack.security.http.ssl.enabled: true # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
extraEnvs: - name: ELASTIC_USERNAME valueFrom: secretKeyRef: name: elastic-auth key: username - name: ELASTIC_PASSWORD valueFrom: secretKeyRef: name: elastic-auth key: password
antiAffinity: 'soft' tolerations: - operator: "Exists"
|
以下是data-value.yaml
的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| clusterName: "elasticsearch"
nodeGroup: "data"
roles: master: "false" ingest: "true" data: "true"
image: "docker.elastic.co/elasticsearch/elasticsearch" imageTag: "7.17.3" imagePullPolicy: "IfNotPresent"
replicas: 3
esJavaOpts: "-Xmx1g -Xms1g" resources: requests: cpu: "1000m" memory: "2Gi" limits: cpu: "1000m" memory: "2Gi"
persistence: enabled: true
volumeClaimTemplate: storageClassName: managed-nfs-storage accessModes: ['ReadWriteOnce'] resources: requests: storage: 20Gi
protocol: http
secretMounts: - name: elastic-certs secretName: elastic-certs path: /usr/share/elasticsearch/config/certs defaultMode: 0755
esConfig: elasticsearch.yml: | xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 # xpack.security.http.ssl.enabled: true # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
extraEnvs: - name: ELASTIC_USERNAME valueFrom: secretKeyRef: name: elastic-auth key: username - name: ELASTIC_PASSWORD valueFrom: secretKeyRef: name: elastic-auth key: password
|
以下是client-value.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| clusterName: "elasticsearch"
nodeGroup: "client"
roles: master: "false" ingest: "false" data: "false"
image: "docker.elastic.co/elasticsearch/elasticsearch" imageTag: "7.17.3" imagePullPolicy: "IfNotPresent"
replicas: 1
esJavaOpts: "-Xmx1g -Xms1g" resources: requests: cpu: "1000m" memory: "2Gi" limits: cpu: "1000m" memory: "2Gi"
persistence: enabled: false
protocol: http
secretMounts: - name: elastic-certs secretName: elastic-certs path: /usr/share/elasticsearch/config/certs defaultMode: 0755
esConfig: elasticsearch.yml: | xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 # xpack.security.http.ssl.enabled: true # xpack.security.http.ssl.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 # xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12
extraEnvs: - name: ELASTIC_USERNAME valueFrom: secretKeyRef: name: elastic-auth key: username - name: ELASTIC_PASSWORD valueFrom: secretKeyRef: name: elastic-auth key: password
service: type: NodePort nodePort: '30200'
|
- 开始部署相关节点
1 2 3
| helm upgrade --install elasticsearch-master -f master-values.yaml --namespace kube-logging ./ helm upgrade --install elasticsearch-data -f data-values.yaml --namespace kube-logging ./ helm upgrade --install elasticsearch-client -f client-values.yaml --namespace kube-logging ./
|
正常情况下看到所有节点都处于running
状态即可
1 2 3 4 5 6 7 8 9
| [root@Online-Beijing-master1 elasticsearch]# kubectl get pods -n kube-logging NAME READY STATUS RESTARTS AGE elasticsearch-client-0 1/1 Running 0 13m elasticsearch-data-0 1/1 Running 0 17m elasticsearch-data-1 1/1 Running 0 17m elasticsearch-data-2 1/1 Running 0 17m elasticsearch-master-0 1/1 Running 0 43m elasticsearch-master-1 1/1 Running 0 43m elasticsearch-master-2 1/1 Running 0 43m
|
安装Kibana
依旧使用helm
的方式进行部署
- 使用
helm pull
拉取Kibana
包来进行解压
1 2
| helm pull elastic/kibana --untar --version 7.17.3 cd kibana
|
- 定义一个名字为
custom-value.yaml
的文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| image: 'kibana' imageTag: '7.17.3'
elasticsearchHosts: 'http://elasticsearch-client:9200'
extraEnvs: - name: 'ELASTICSEARCH_USERNAME' valueFrom: secretKeyRef: name: elastic-auth key: username - name: 'ELASTICSEARCH_PASSWORD' valueFrom: secretKeyRef: name: elastic-auth key: password resources: requests: cpu: '500m' memory: '1Gi' limits: cpu: '500m' memory: '1Gi'
kibanaConfig: kibana.yml: | i18n.locale: "zh-CN" service: type: NodePort nodePort: '30601'
|
- 部署
kibana
1
| helm install kibana -f custom-value.yaml --namespace kube-logging .
|
部署Fluentd
Fluentd 是一个高效的日志聚合器,是用 Ruby 编写的,并且可以很好地扩展。对于大部分企业来说,Fluentd 足够高效并且消耗的资源相对较少,另外一个工具 Fluent-bit
更轻量级,占用资源更少,但是插件相对 Fluentd 来说不够丰富,所以整体来说,Fluentd 更加成熟,使用更加广泛,所以这里我们使用 Fluentd 来作为日志收集工具。
工作原理
Fluentd 通过一组给定的数据源抓取日志数据,处理后(转换成结构化的数据格式)将它们转发给其他服务,比如 Elasticsearch、对象存储等等。Fluentd 支持超过 300 个日志存储和分析服务,所以在这方面是非常灵活的。主要运行步骤如下:
- 首先 Fluentd 从多个日志源获取数据
- 结构化并且标记这些数据
- 然后根据匹配的标签将数据发送到多个目标服务去
- 官方文档
日志源配置
比如我们这里为了收集 Kubernetes 节点上的所有容器日志,就需要做如下的日志源配置:
- id:表示引用该日志源的唯一标识符,该标识可用于进一步过滤和路由结构化日志数据
- type:Fluentd 内置的指令,tail 表示 Fluentd 从上次读取的位置通过 tail 不断获取数据,另外一个是 http 表示通过一个 GET 请求来收集数据。
- path:
tail
类型下的特定参数,告诉 Fluentd 采集 /var/log/containers 目录下的所有日志,这是 docker 在 Kubernetes 节点上用来存储运行容器 stdout 输出日志数据的目录。 - pos_file:检查点,如果 Fluentd 程序重新启动了,它将使用此文件中的位置来恢复日志数据收集。
- tag:用来将日志源与目标或者过滤器匹配的自定义字符串,Fluentd 匹配源/目标标签来路由日志数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <source> @id fluentd-containers.log @type tail # Fluentd 内置的输入方式,其原理是不停地从源文件中获取新的日志,类似于tail命令 path /var/log/containers/*.log # 挂载的宿主机容器日志地址 pos_file /var/log/es-containers.log.pos tag raw.kubernetes.* # 设置日志标签 read_from_head true <parse> # 多行格式化成JSON @type multi_format # 使用 multi-format-parser 解析器插件 <pattern> format json # JSON 解析器 time_key time # 指定事件时间的时间字段 time_format %Y-%m-%dT%H:%M:%S.%NZ # 时间格式 </pattern> <pattern> format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/ time_format %Y-%m-%dT%H:%M:%S.%N%:z </pattern> </parse> </source>
|
过滤
由于 Kubernetes 集群中应用太多,也还有很多历史数据,所以我们可以只将某些应用的日志进行收集,比如我们只采集具有discovery-log=true
这个 Label 标签的 Pod 日志,这个时候就需要使用 filter。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 删除无用的属性 <filter kubernetes.**> @type record_transformer remove_keys $.docker.container_id,$.kubernetes.container_image_id,$.kubernetes.pod_id,$.kubernetes.namespace_id,$.kubernetes.master_url,$.kubernetes.labels.pod-template-hash </filter> # 只保留具有discovery-log=true标签的Pod日志 <filter kubernetes.**> @id filter_log @type grep <regexp> key $.kubernetes.labels.discovery-log pattern ^true$ </regexp> </filter>
|
路由设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <match **> @id elasticsearch @type elasticsearch @log_level info include_tag_key true type_name fluentd host "#{ENV['OUTPUT_HOST']}" port "#{ENV['OUTPUT_PORT']}" logstash_format true <buffer> @type file path /var/log/fluentd-buffers/kubernetes.system.buffer flush_mode interval retry_type exponential_backoff flush_thread_count 2 flush_interval 5s retry_forever retry_max_interval 30 chunk_limit_size "#{ENV['OUTPUT_BUFFER_CHUNK_LIMIT']}" queue_limit_length "#{ENV['OUTPUT_BUFFER_QUEUE_LIMIT']}" overflow_action block </buffer> </match>
|
- match:标识一个目标标签,后面是一个匹配日志源的正则表达式,我们这里想要捕获所有的日志并将它们发送给 Elasticsearch,所以需要配置成**。
- id:目标的一个唯一标识符。
- type:支持的输出插件标识符,我们这里要输出到 Elasticsearch,所以配置成 elasticsearch,这是 Fluentd 的一个内置插件。
- log_level:指定要捕获的日志级别,我们这里配置成 info,表示任何该级别或者该级别以上(INFO、WARNING、ERROR)的日志都将被路由到 Elsasticsearch。
- host/port:定义 Elasticsearch 的地址,也可以配置认证信息,我们的 Elasticsearch 不需要认证,所以这里直接指定 host 和 port 即可。
- logstash_format:Elasticsearch 服务对日志数据构建反向索引进行搜索,将 logstash_format 设置为 true,Fluentd 将会以 logstash 格式来转发结构化的日志数据。
- Buffer: Fluentd 允许在目标不可用时进行缓存,比如,如果网络出现故障或者 Elasticsearch 不可用的时候。缓冲区配置也有助于降低磁盘的 IO。
开始部署Fluentd
要收集 Kubernetes 集群的日志,直接用DasemonSet
控制器来部署 Fluentd 应用,这样,它就可以从 Kubernetes 节点上采集日志,确保在集群中的每个节点上始终运行一个 Fluentd 容器。当然可以直接使用 Helm 来进行一键安装,为了能够了解更多实现细节,我们这里还是采用手动方法来进行安装。
- 首先创建
fluentd
的configmap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| kind: ConfigMap apiVersion: v1 metadata: name: fluentd-conf namespace: kube-logging data: containerd.input.conf: |- <source> @id containerd-fluentd-beta.log # 唯一Id:运行时+收集插件+环境 @type tail # Fluentd 内置的输入方式,其原理是不停地从源文件中获取新的日志 path /var/log/containers/*.log # Docker 容器日志路径 pos_file /var/log/es-containers.log.pos # 记录读取的位置 tag raw.kubernetes.* # 设置日志标签 read_from_head true # 从头读取 <parse> # 多行格式化成JSON # 可以使用我们介绍过的 multiline 插件实现多行日志 @type multi_format # 使用 multi-format-parser 解析器插件 <pattern> format json # JSON解析器 time_key time # 指定事件时间的时间字段 time_format %Y-%m-%dT%H:%M:%S.%NZ # 时间格式 </pattern> <pattern> format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/ time_format %Y-%m-%dT%H:%M:%S.%N%:z </pattern> </parse> </source>
<match raw.kubernetes.**> @id raw.kubernetes @type detect_exceptions remove_tag_prefix raw message log multiline_flush_interval 5 </match>
<filter **> @id filter_concat @type concat key message multiline_end_regexp /\n$/ separator "" </filter>
<filter kubernetes.**> @id filter_kubernetes_metadata @type kubernetes_metadata </filter>
<filter kubernetes.**> @id filter_parser @type parser key_name log reserve_data true remove_key_name_field true <parse> @type multi_format <pattern> format json </pattern> <pattern> format none </pattern> </parse> </filter>
<filter kubernetes.**> @type record_transformer remove_keys $.docker.container_id,$.kubernetes.container_image_id,$.kubernetes.pod_id,$.kubernetes.namespace_id,$.kubernetes.master_url,$.kubernetes.labels.pod-template-hash </filter>
<filter kubernetes.**> @id filter_log @type grep <regexp> key $.kubernetes.labels.kubernetes.log/fluentd pattern ^true$ </regexp> </filter>
forward.input.conf: |- # 监听通过TCP发送的消息 <source> @id forward @type forward </source>
output.conf: |- <match **> @id elasticsearch @type elasticsearch @log_level info include_tag_key true host elasticsearch-client port 9200 user elastic # FLUENT_ELASTICSEARCH_USER | FLUENT_ELASTICSEARCH_PASSWORD password elastic-master logstash_format true logstash_prefix kubernetes-cluster request_timeout 30s <buffer> @type file path /var/log/fluentd-buffers/kubernetes.system.buffer flush_mode interval retry_type exponential_backoff flush_thread_count 2 flush_interval 5s retry_forever retry_max_interval 30 chunk_limit_size 2M queue_limit_length 8 overflow_action block </buffer> </match>
|
- 创建相关的Rbac权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| --- apiVersion: v1 kind: ServiceAccount metadata: name: fluentd namespace: kube-logging
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: fluentd rules: - apiGroups: - "" resources: - pods - namespaces verbs: - get - list - watch
--- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: fluentd roleRef: kind: ClusterRole name: fluentd apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: fluentd namespace: kube-logging
|
- 创建
fluentd
的daemonset
这个是最新的版本还在研究中,用下面的版本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd namespace: kube-logging labels: k8s-app: fluentd-logging version: v1 spec: selector: matchLabels: k8s-app: fluentd-logging version: v1 template: metadata: labels: k8s-app: fluentd-logging version: v1 spec: serviceAccount: fluentd serviceAccountName: fluentd tolerations: - key: node-role.kubernetes.io/control-plane effect: NoSchedule - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: fluentd image: fluent/fluentd-kubernetes-daemonset:v1-debian-elasticsearch env: - name: K8S_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: FLUENT_ELASTICSEARCH_HOST value: "elasticsearch-client-headless.kube-logging.svc.cluster.local" - name: FLUENT_ELASTICSEARCH_PORT value: "9200" - name: FLUENT_ELASTICSEARCH_SCHEME value: "http" - name: FLUENT_ELASTICSEARCH_SSL_VERIFY value: "true" - name: FLUENT_ELASTICSEARCH_SSL_VERSION value: "TLSv1_2" - name: FLUENT_ELASTICSEARCH_USER value: "elastic" - name: FLUENT_ELASTICSEARCH_PASSWORD value: "elastic-master" - name: FLUENT_ELASTICSEARCH_LOGSTASH_PREFIX value: "kubernetes-cluster" resources: limits: memory: 200Mi requests: cpu: 100m memory: 200Mi volumeMounts: - name: varlog mountPath: /var/log - name: fluentconfig mountPath: /fluentd/etc/custom - name: dockercontainerlogdirectory mountPath: /var/log/pods readOnly: true terminationGracePeriodSeconds: 30 volumes: - name: varlog hostPath: path: /var/log - name: fluentconfig configMap: name: fluentd-conf - name: dockercontainerlogdirectory hostPath: path: /var/log/pods
|
麻烦用下面的进行部署
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd namespace: kube-logging labels: app: fluentd kubernetes.io/cluster-service: 'true' spec: selector: matchLabels: app: fluentd template: metadata: labels: app: fluentd kubernetes.io/cluster-service: 'true' spec: tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule serviceAccountName: fluentd containers: - name: fluentd image: quay.io/fluentd_elasticsearch/fluentd:v3.4.0 volumeMounts: - name: fluentconfig mountPath: /etc/fluent/config.d - name: varlog mountPath: /var/log volumes: - name: fluentconfig configMap: name: fluentd-conf - name: varlog hostPath: path: /var/log
|
关于保留指定标签的问题
部署完成以后我发现一直有一个小问题,就是无论我如何设置label
都无法让elasticsearch
获取到正常的数据。
根据这个问题,我进行了更细致的排查。现在得出了如下的结论。
可能是由于我对知识的缺乏,我定义的是Deployment
当中的label
标签,但是这个label
标识只作用于Deployment
本身,通常用作kubernete
集群中的选择器匹配,例如我们的Service
要去匹配某个Deployment
。
关于spec.template.metadata.labels
,我发现这个才是我们正确要匹配的label
标签选项,因为这些标签用于标识Deployment
所创建的Pod
所以最后总结出来的问题就是,我们上面的fluentd
中写的过滤插件key $.kubernetes.labels.kubernetes.log/fluentd
中所匹配的label
标签应当是spec.template.metadata.labels
的label
1 2 3 4 5 6 7 8 9 10 11
| spec: replicas: 2 selector: matchLabels: app: canary template: metadata: creationTimestamp: null labels: app: canary kubernetes.log/fluentd: 'true'
|