loki官网上有使用k8s直接安装promtail的教程,但说得比较简单,缺少落地例子。所以特意补充案例,并标注其中的坑点。
网上也有很多k8s安装promtail的例子,但都是基于helm安装的。
环境说明:提前安装了grafana和loki,本案例只展示promtail的k8s安装并接入已有loki。
一、daemonSet.yml:
这里有2个地方是重点、重点、重点,是导致promtail无法获取k8s的根因:
1. daemon的环境变量要设置HOSTNAME,并与node节点的名称一样(具体配置看下文标红的fieldPath: spec.nodeName);
2. 需要挂载k8s的日志目录到promtail容器中(具体配置看下文的volumeMounts)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: promtail-daemonset
namespace: default
labels:
app: promtail
spec:
selector:
matchLabels:
app: promtail
type: daemonset
author: danny
template:
metadata:
labels:
app: promtail
type: daemonset
author: danny
spec:
containers:
- name: promtail
image: grafana/promtail:latest
args:
- -config.file=/etc/promtail/promtail.yaml
env:
- name: HOSTNAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: spec.nodeName
- name: TZ
value: Asia/Shanghai
ports:
- containerPort: 3101
name: http-metrics
protocol: TCP
securityContext:
# readOnlyRootFilesystem: true
runAsGroup: 0
runAsUser: 0
volumeMounts:
- mountPath: /etc/promtail
name: promtail-configmap
- mountPath: /run/promtail
name: run
- mountPath: /var/lib/kubelet/pods
name: kubelet
readOnly: true
- mountPath: /var/lib/docker/containers
name: docker
readOnly: true
- mountPath: /var/log/pods
name: pod-log
readOnly: true
- name: timezone
mountPath: /etc/localtime
volumes:
- configMap:
defaultMode: 420
name: promtail-configmap
name: promtail-configmap
- name: timezone
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
- hostPath:
path: /run/promtail
type: ""
name: run
- hostPath:
path: /var/lib/kubelet/pods
type: ""
name: kubelet
- hostPath:
path: /var/lib/docker/containers
type: ""
name: docker
- hostPath:
path: /var/log/pods
type: ""
name: pod-log
serviceAccount: promtail-serviceaccount
serviceAccountName: promtail-serviceaccount
updateStrategy:
type: RollingUpdate
二、configMap.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: promtail-configmap
data:
promtail.yaml: |-
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://${ip}/loki/api/v1/push #${ip}填入loki的对应地址
scrape_configs:
- job_name: kubernetes-pods-app
pipeline_stages:
- docker: {}
kubernetes_sd_configs:
- role: pod
relabel_configs:
- action: drop
regex: .+
source_labels:
- __meta_kubernetes_pod_label_name
- source_labels:
- __meta_kubernetes_pod_label_app
target_label: __service__
- source_labels:
- __meta_kubernetes_pod_node_name
target_label: __host__
- action: drop
regex: ''
source_labels:
- __service__
- action: labelmap
regex: __meta_kubernetes_pod_label_(.+)
- replacement: /var/log/pods/*$1/*.log
separator: /
source_labels:
- __meta_kubernetes_pod_uid
- __meta_kubernetes_pod_container_name
target_label: __path__
- source_labels:
- __meta_kubernetes_pod_node_name
target_label: __host__
这relabel不能少,用于区分不用k8s节点上报的信息。官网也特别提示:
三、serviceAccount.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: promtail-serviceaccount
四、clusterRole.yaml
定义clusterRole,用于获取server-api权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: promtail-clusterrole
rules:
- apiGroups: [""]
resources:
- nodes
- services
- pods
verbs:
- get
- watch
- list
五、roleBinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: promtail-clusterrolebinding
subjects:
- kind: ServiceAccount
name: promtail-serviceaccount
namespace: default
roleRef:
kind: ClusterRole
name: promtail-clusterrole
#name: admin
apiGroup: rbac.authorization.k8s.io
效果图: