EFK - Kulichanin/speedtest GitHub Wiki
EFK Stack
Развертывание efk стака для логирования кластера kubernetes
Согласно оф. документации команда elastic предлагает Elastic Cloud on Kubernetes(ECK). Данный вариант предлагает максимальное эффективное управление изменениями кластера, как горизонтально так и вертикально
Подготовка кластера
Для установки необходимо скачать репозиторий cloud-on-k8s
git clone https://github.com/elastic/cloud-on-k8s.git
В виду локальных ограничений необходимо изменить репозиторий eck оператора cloud-on-k8s/deploy/eck-operator/values.yaml
/:20
image:
# repository is the container image prefixed by the registry name.
repository: elastic/eck-operator
# pullPolicy is the container image pull policy.
pullPolicy: IfNotPresent
# tag is the container image tag. If not defined, defaults to chart appVersion.
tag: "2.16.1"
# fips specifies whether the operator will use a FIPS compliant container image for its own StatefulSet image.
# This setting does not apply to Elastic Stack applications images.
# Can be combined with config.ubiOnly.
fips: false
/:204
containerRegistry: docker.io
Установка eck оператора
Установка происходить с помощью helm в namespace elastic-system
helm install elastic-operator cloud-on-k8s/deploy/eck-operator -n elastic-system --create-namespace
Определить namespace elastic-system по умолчанию для удобства
kubectl config set-context --current --namespace=elastic-system
Получение метрик из eck
Включите в ConfigMap настройку метрик.
cat <<EOF | kubectl apply -f -
kind: ConfigMap
apiVersion: v1
metadata:
name: elastic-operator
namespace: elastic-system
data:
eck.yaml: |-
log-verbosity: 0
metrics-port: 8080
metrics-host: 0.0.0.0
container-registry: docker.io
max-concurrent-reconciles: 3
ca-cert-validity: 8760h
ca-cert-rotate-before: 24h
cert-validity: 8760h
cert-rotate-before: 24h
disable-config-watch: false
exposed-node-labels: [topology.kubernetes.io/.*,failure-domain.beta.kubernetes.io/.*]
set-default-security-context: auto-detect
kube-client-timeout: 60s
elasticsearch-client-timeout: 180s
disable-telemetry: false
distribution-channel: all-in-one
validate-storage-class: true
enable-webhook: true
webhook-name: elastic-operator.elastic-system.k8s.elastic.co
webhook-port: 9443
operator-namespace: elastic-system
enable-leader-election: true
elasticsearch-observation-interval: 10s
ubi-only: false
EOF
Исправьте StatefulSet, чтобы открыть порт метрик.
kubectl patch sts -n elastic-system elastic-operator --patch-file=/dev/stdin <<-EOF
spec:
template:
spec:
containers:
- name: manager
ports:
- containerPort: 9443
name: https-webhook
protocol: TCP
- containerPort: 8080
protocol: TCP
name: metrics
EOF
При использовании оператора Prometheus установите PodMonitor, чтобы разрешить Prometheus выполнять сбор конечной точки метрик.
cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: monitor-operator
namespace: elastic-system
labels:
app.kubernetes.io/component: metrics
release: kube-prometheus-stack
spec:
podMetricsEndpoints:
- port: metrics
path: /metrics
interval: 1m
scrapeTimeout: 30s
namespaceSelector:
matchNames:
- elastic-system
selector:
matchLabels:
app.kubernetes.io/name: elastic-operator
EOF
Установка elastic
Установка происходит через kubectl и обращение к новыму ресурсу Elasticsearch
Данный пример создает daemonset, который меняет max_map_count, после чего происходит установка кластера elasticsearch(1 ноды в режиме master и 2 ноды в режиме data). Также определен volumeClaimTemplates размером 1 гб и 5 гб в зависимости от роли.
elastic.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: max-map-count-setter
labels:
k8s-app: max-map-count-setter
spec:
selector:
matchLabels:
name: max-map-count-setter
template:
metadata:
labels:
name: max-map-count-setter
spec:
initContainers:
- name: max-map-count-setter
image: docker.io/bash:5.2.21
resources:
limits:
cpu: 100m
memory: 32Mi
securityContext:
privileged: true
runAsUser: 0
command: ['/usr/local/bin/bash', '-e', '-c', 'echo 262144 > /proc/sys/vm/max_map_count']
containers:
- name: sleep
image: docker.io/bash:5.2.21
command: ['sleep', 'infinity']
---
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: elastic-cluster
namespace: elastic-system
spec:
version: 8.17.1
image: elastic/elasticsearch:8.17.1
nodeSets:
- name: master-nodes
count: 1
config:
node.roles: ["master"]
volumeClaimTemplates:
- metadata:
name: elasticsearch-data # Do not change this name unless you set up a volume mount for the data path.
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs-sc
podTemplate:
spec:
# This init container ensures that the max_map_count setting has been applied before starting Elasticsearch.
# This is not required, but is encouraged when using the previous Daemonset to set max_map_count.
# Do not use this if setting config.node.store.allow_mmap: false
initContainers:
- name: max-map-count-check
command: ['sh', '-c', "while true; do mmc=$(cat /proc/sys/vm/max_map_count); if [ ${mmc} -eq 262144 ]; then exit 0; fi; sleep 1; done"]
- name: data
count: 2
config:
node.roles: ["data"]
volumeClaimTemplates:
- metadata:
name: elasticsearch-data # Do not change this name unless you set up a volume mount for the data path.
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: nfs-sc
Применим файл
kubectl apply -f elastic.yml
Проверка работы elastic
Получим пароль из соответствующего секрета
kubectl get secrets elastic-cluster-es-elastic-user -o json | jq -r .data.elastic | base64 -d
Прокинем порт для работы обращение через localhost
kubectl port-forward service/elastic-cluster-es-http 9200
В отдельном окне обратимся к сервису
curl https://localhost:9200 -u elastic:PASSWORD -k
Получение метрик из нод кластера
На основе Elasticsearch Exporter добавим в манифест создания Elasticsearch класстера под для сбора метрик.
Согласно документации определим securityContext для запуска пода с версией elasticsearch 8.17.1
Для других версий необходимо ознакомиться с документацией!
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: elastic-cluster
namespace: elastic-system
spec:
version: 8.17.1
image: elastic/elasticsearch:8.17.1
nodeSets:
- name: default
count: 1
volumeClaimTemplates:
- metadata:
name: elasticsearch-data # Do not change this name unless you set up a volume mount for the data path.
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs-sc
podTemplate:
spec:
# In versions of Elasticsearch before 8.0.0, the Elastisearch container is run as root and its entrypoint is responsible to run the Elasticsearch process with the elasticsearch user (defined with ID 1000).
securityContext:
runAsUser: 1000
containers:
- name: metrics
image: quay.io/prometheuscommunity/elasticsearch-exporter:latest
imagePullPolicy: IfNotPresent
command: ["elasticsearch_exporter",
"--es.uri=https://127.0.0.1:9200",
"--es.ssl-skip-verify",
"--es.timeout=120s"]
env:
- name: ES_USERNAME
value: elastic
- name: ES_PASSWORD
valueFrom:
secretKeyRef:
name: elastic-cluster-es-elastic-user
key: elastic
ports:
- containerPort: 9114
name: metrics
Пароль для подключения берем из секрета, который создает eck при создании кластера
Изменим стандаратный service/elastic-cluster-es-http, чтобы открыть порт метрик. Это можно сделать добавив в манифест для создания кластера Elasticsearch
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: elastic-cluster
namespace: elastic-system
spec:
version: 8.17.1
image: elastic/elasticsearch:8.17.1
nodeSets:
- name: default
count: 1
volumeClaimTemplates:
- metadata:
name: elasticsearch-data # Do not change this name unless you set up a volume mount for the data path.
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs-sc
podTemplate:
spec:
# In versions of Elasticsearch before 8.0.0, the Elastisearch container is run as root and its entrypoint is responsible to run the Elasticsearch process with the elasticsearch user (defined with ID 1000).
# In the background, ECK uses an initContainer to make sure that the data volume is writable for the elasticsearch user. https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-security-context.html
securityContext:
runAsUser: 1000
containers:
- name: elasticsearch
env:
- name: ES_JAVA_OPTS
value: "-Xms1g -Xmx1g"
- name: metrics
image: quay.io/prometheuscommunity/elasticsearch-exporter:latest
imagePullPolicy: IfNotPresent
command: ["elasticsearch_exporter",
"--es.uri=https://127.0.0.1:9200",
"--es.ssl-skip-verify",
"--es.timeout=120s"]
env:
- name: ES_USERNAME
value: elastic
- name: ES_PASSWORD
valueFrom:
secretKeyRef:
name: elastic-cluster-es-elastic-user
key: elastic
ports:
- containerPort: 9114
name: metrics
http:
service:
metadata:
labels:
service: "elastic-cluster-es-http"
spec:
ports:
- name: https
port: 9200
protocol: TCP
targetPort: 9200
- name: metrics
port: 9114
protocol: TCP
targetPort: 9114
При использовании оператора Prometheus установите ServiceMonitor, чтобы разрешить Prometheus выполнять сбор конечной точки метрик.
cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: monitor-cluster
namespace: elastic-system
labels:
app.kubernetes.io/component: metrics
release: kube-prometheus-stack
spec:
selector:
matchLabels:
service: "elastic-cluster-es-http"
endpoints:
- interval: 5s
targetPort: metrics
path: /metrics
EOF
Изменения в ресурсах JMV
Согласно документации вы можете настроить Pod, созданные для каждого приложения стека Elastic, изменив соответствующее podTemplate.
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: quickstart
spec:
version: 8.17.2
nodeSets:
- name: default
count: 1
podTemplate:
spec:
containers:
- name: elasticsearch
env:
- name: ES_JAVA_OPTS
value: "-Xms4g -Xmx4g"
Установка kibana
Установка происходит через kubectl и обращение к новыму ресурсу Elasticsearch
Пример создания kibana c типом service LoadBalancer
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: elastic-cluster
namespace: elastic-system
spec:
version: 8.17.1
image: kibana:8.17.1
count: 1
elasticsearchRef:
name: elastic-cluster
namespace: elastic-system
Настройка HTTPS сертификатов
По умолчанию создается ClusterIP служба, которая ассоциируется с развертыванием Kibana. Если вы хотите предоставить Kibana внешне с помощью балансировщика нагрузки, рекомендуется включить пользовательское DNS-имя или IP в самогенерируемый сертификат.
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: elastic-cluster
namespace: elastic-system
spec:
version: 8.17.1
image: kibana:8.17.1
count: 1
elasticsearchRef:
name: elastic-cluster
namespace: elastic-system
http:
service:
spec:
type: LoadBalancer
tls:
selfSignedCertificate:
subjectAltNames:
- ip: 1.2.3.4
- dns: kibana.example.com
Согласно документации нет четкого подход к доступу через ingress, поэтому можно просто отключить автоматическую генерацию ssl
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: kibana-sample
spec:
version: 8.17.2
count: 1
elasticsearchRef:
name: "elasticsearch-sample"
http:
tls:
selfSignedCertificate:
disabled: true
Установка fluent-bit
Подготовка к установке
Для установки необходимо скачать репозиторий c помощью helm
helm repo add fluent https://fluent.github.io/helm-charts
helm repo update
helm pull fluent/fluent-bit --untar
Изменить данные в файле ./fluent-bit/values.yaml
для подлючения к кластеру elasticsearch
Добавим tolerations, чтобы запуск происходил на всех нодах с помощью daemonset
:/295
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
:/315
env:
- name: ELASTICSEARCH_PASSWORD
valueFrom:
secretKeyRef:
name: elastic-cluster-es-elastic-user
key: elastic
:/359
extraVolumes:
- name: elastic-certs
secret:
secretName: elastic-cluster-es-http-certs-internal
items:
- key: ca.crt
path: certs/es.ca
- key: tls.crt
path: certs/es.crt
- key: tls.key
path: certs/es.key
extraVolumeMounts:
- name: elastic-certs
mountPath: "/opt/"
readOnly: true
:/419
outputs: |
[OUTPUT]
Name es
Match kube.*
Host elastic-cluster-es-http
Logstash_Format On
Logstash_Prefix kube
Retry_Limit False
Suppress_Type_Name On
Buffer_Size 1Mb
http_user elastic
http_passwd ${ELASTICSEARCH_PASSWORD}
tls on
tls.debug 4
tls.verify on
tls.ca_file /opt/certs/es.ca
tls.crt_file /opt/certs/es.crt
tls.key_file /opt/certs/es.key
[OUTPUT]
Name es
Match host.*
Host elastic-cluster-es-http
Logstash_Format On
Logstash_Prefix node
Retry_Limit False
Suppress_Type_Name On
Buffer_Size 1Mb
http_user elastic
http_passwd ${ELASTICSEARCH_PASSWORD}
tls on
tls.debug 4
tls.verify on
tls.ca_file /opt/certs/es.ca
tls.crt_file /opt/certs/es.crt
tls.key_file /opt/certs/es.key
Установка
Установка с корректной конфигурацией
helm install fluent-bit -n elastic-system ./fluent-bit/ -f fluent-bit/values.yaml
После успешного развертывания можем зайти в kibana и убедиться в получение данных