2 december 2022
1 april 2026
Leestijd 17 min
How to: een EFK-stack implementeren in Kubernetes met xpack-beveiliging
<span id="hs_cos_wrapper_name" class="hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text" style="" data-hs-cos-general-type="meta_field" data-hs-cos-type="text" >How to: een EFK-stack implementeren in Kubernetes met xpack-beveiliging</span>
Share this via:

In deze Kubernetes tutorial leer je hoe je een EFK stack op Kubernetes instelt met xpack beveiligingsfunctie ingeschakeld voor log streaming, log analyse en log monitoring.

Als je meerdere applicaties en diensten op een Kubernetes-cluster draait, is het zinvoller om alle logs van je Kubernetes-cluster te streamen naar één gecentraliseerde loginfrastructuur voor eenvoudige loganalyse. Dit kan u helpen bij het snel sorteren en analyseren van de grote hoeveelheid loggegevens die uw Pods produceren. Door de beveiligingsfunctie van xpack in te schakelen, kunt u gebruikers, rollen, weergaven en .... aanmaken en beheren. Dit geeft de mogelijkheid om bepaalde rechten te geven voor het bekijken, bewerken, maken van dashboards, ... voor een subset van applicatielogs (indexen).

Een populaire gecentraliseerde logging oplossing is de Elasticsearch, Fluentden Kibana(EFK) stack.

Wat doet elke component?

  • Elasticsearch: vangt binnenkomende gegevens op en slaat deze op in indexen.
  • Fluentd: volgt applicaties in uw cluster en stuurt deze rechtstreeks naar Elasticsearch.
  • Kibana: maakt het mogelijk om logs te bekijken, queries uit te voeren, een eigen dashboard te maken, ... vanuit Elasticsearch Indexen (data).

Elastic heeft onlangs verklaard dat beveiligingsfuncties standaard worden gedistribueerd met de basislicentie.


Elastic heeft vanaf Elastic Stack 6.8 en 7.1 een aantal beveiligingsfuncties gratis beschikbaar gesteld als onderdeel van de standaarddistributie (basislicentie). Dit nieuwe functieaanbod omvat de mogelijkheid om netwerkverkeer te versleutelen met SSL, gebruikers aan te maken en te beheren, rollen te definiëren die toegang op index- en clusterniveau beschermen en Kibana volledig te beveiligen.

1. Vereisten

Voordat we met deze handleiding kunnen beginnen, moet je ervoor zorgen dat je de volgende dingen tot je beschikking hebt:

  • Een Kubernetes 1.10+ cluster met rolgebaseerd toegangsbeheer (RBAC) ingeschakeld.
  • De opdrachtregeltool kubectl geïnstalleerd op uw lokale machine, geconfigureerd om verbinding te maken met uw cluster.
  • (Optioneel) SealedSecret Controller ingezet op het cluster en kubeseal geïnstalleerd op je lokale machine.

Zodra je deze componenten hebt ingesteld, ben je klaar om te beginnen met deze handleiding. Laten we beginnen!

2. De namespaces aanmaken

Laten we beginnen met het aanmaken van de benodigde namespaces voor elke applicatie.

Elasticsearch naamruimte:

soort: NamespaceapiVersion: v1metadata: name: elasticsearch group: elasticsearch
YAML

FluentD naamruimte:

soort: NaamruimteapiVersie: v1metadata: naam: fluentd groep: fluentd
YAML

Kibana naamruimte:

soort: NamespaceapiVersion: v1metadata: name: fluentd group: fluentd
YAML

Nadat we de yaml-bestanden hebben gemaakt, kunnen we de yaml-bestanden uitrollen naar het cluster:

kubectl create -f elasticsearch.yaml -f kibana.yaml -f fluentd.yaml 
Standaard

De volgende uitvoer zou moeten verschijnen:

namespace/elasticsearch created namespace/kibana created namespace/fluentd created
Standaard

We kunnen valideren of de namespaces met succes zijn aangemaakt door het volgende commando uit te voeren:

kubectl get namespaces
Standaard

De volgende uitvoer zou moeten verschijnen:

NAAM STATUS LEEFTIJD default Actief 15d kube-system Actief 15d elasticsearch Actief 1m kibana Actief 1m fluentd Actief 1m
Standaard

3. Elasticsearch Statefulset implementeren

Eerst moeten we Elasticsearch implementeren. Elasticsearch is de kerncomponent in de stack, Fluentd en Kibana kunnen niet werken zonder ElasticSearch.

U kunt meer informatie over Elasticsearch vinden door op deze link te klikken: https://www.elastic.co/what-is/elasticsearch

3.1 ServiceAccount aanmaken

Laten we eerst beginnen met het aanmaken van de RBAC resources. We zullen de Elasticsearch ServiceAccount genoeg rechten geven om het cluster te verkennen en naar andere Elasticsearch-nodes te zoeken.

apiVersion: v1soort: ServiceAccountmetadata: naam: elasticsearch naamruimte: elasticsearch labels: app: elasticsearch
YAML

We hebben onze ServiceAccount, nu moeten we de ClusterRole maken en deze binden aan de elasticsearch ServiceAccount.

soort: ClusterRoleapiVersion: rbac.authorization.k8s.io/v1metadata: naam: elasticsearch labels: k8s-app: elasticsearch kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcilerules:- apiGroups: - "" resources: - "services" - "namespaces" - "endpoints" verbs: - "get"
YAML

Binden aan de ServiceAccount.

soort: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: namespace: elasticsearch naam: elasticsearch labels: k8s-app: elasticsearch kubernetes.io/cluster-service: "true" addonmanager.kubernetes.io/mode: Reconcilesubjects:- soort: ServiceAccount naam: elasticsearch namespace: elasticsearch apiGroup: ""roleRef: soort: ClusterRole naam: elasticsearch apiGroup: ""
YAML

3.2 Headless services aanmaken

Voor de volgende stap hebben we een Service resource in het cluster nodig. We maken een Headless Service resource aan met de naam elasticsearch in de namespace elasticsearch. Wanneer we onze Elasticsearch StatefulSet aan deze service koppelen, retourneert de service DNS A-records (service-name.namespace.svc.cluster.local) die verwijzen naar Elasticsearch Pods met het label app: elasticsearch. We zullen deze DNS-records later configureren in onze Statefulset, zodat Elasticsearch naar deze knooppunten zal zoeken.

apiVersion: v1kind: Servicemetadata: name: elasticsearch namespace: elasticsearch labels: app: elasticsearchspec: selector: app: elasticsearch ports: - name: rest port: 9200 targetPort: 9200 - naam: transport port: 9300 doelpoort: 9300
YAML

Laten we onze yaml-bestanden inzetten op het cluster:

kubectl create -f Service.yaml -f ServiceAccount.yaml -f ClusterRole.yaml -f ClusterRoleBinding.yaml
Standaard

Laten we nu eens kijken of de elasticsearch Service met succes is ingezet:

kubectl get services -n elasticsearch
Standaard

De volgende uitvoer zou moeten verschijnen:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch ClusterIP None <none> 9200/TCP,9300/TCP 1m
Standaard

3.3 Statefulset aanmaken

apiVersion: apps/v1soort: StatefulSet  metadata:  naam: elasticsearch naamruimte: elasticsearchspec: serviceName: elasticsearch replicas: 3 updateStrategy: type: OnDelete selector: matchLabels: app: elasticsearch template: metadata: labels: app: elasticsearch spec: securityContext: fsGroup: 1000 initContainers: - naam:  increase-vm-max-map image: busybox imagePullPolicy: IfNotPresent securityContext: privileged: true commando: [ "sysctl", "-w", "vm.max_map_count=262144" ] containers: - naam: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch:8.3.2 env: - naam: node.name valueFrom: fieldRef: fieldPath: metadata.name - naam: NODE_MASTER valueFrom: configMapKeyRef: naam:  elasticsearch-config key: NODE_MASTER - naam: NODE_DATA valueFrom: configMapKeyRef: naam:  elasticsearch-config key: NODE_DATA - naam: NUMBER_OF_MASTERS valueVan: configMapKeyRef: naam:  elasticsearch-config key: NUMBER_OF_MASTERS - naam: NUMBER_OF_REPLICAS waardeVan: configMapKeyRef: naam:  elasticsearch-config key: NUMBER_OF_REPLICAS - name: ES_JAVA_OPTS valueFrom: configMapKeyRef: name:  elasticsearch-config key: ES_JAVA_OPTS - name: ES_PORT value: "9200" - naam: ELASTIC_PASSWORD waardeVan: secretKeyRef: naam:  elastic-credentials sleutel: ELASTIC_PASSWORD poorten: - containerPort: 9200 naam: rest protocol: TCP - containerPort: 9300 naam: transport protocol: TCP volumeMounts: - naam:  elasticsearch-data mountPath: /usr/share/elasticsearch/data - naam:  elasticsearch-yml mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml resources: requests: cpu: "1000m" memory: "2Gi" limits: cpu: "1000m" memory: "2Gi     
       volumes: - naam:  elasticsearch-yml configMap: naam:  elasticsearch-config items: - key: elasticsearch.yml path: elasticsearch.yml volumeClaimTemplates: - metadata: naam:  elasticsearch-data annotations: volume.beta.kubernetes.io/storage-class: gp3 spec: accessModes: [ "ReadWriteOnce" ] bronnen: requests: storage: 50Gi
YAML

We hebben een aantal omgevingsvariabelen gedefinieerd in onze Statefulset bronnen. Sommige variabelen komen uit ConfigMap en sommige uit een Secret.

Secret bevat het wachtwoord van de Elasticsearch admin gebruiker.

Voer de volgende opdracht uit om een yaml-bestand te maken voor het elasticsearch admin-wachtwoord:

# Maak SealedSecret aan voor het beheerderswachtwoord van elasticsearch kubectl -n elasticsearch create secret generic elastic-credentials \ --from-literal=ELASTIC_PASSWORD='STRONG-PASSWORD' \ --dry-run=client -o yaml | ${KUBESEAL_BINARY} --cert ${KUBESEAL_CERT_PATH} --format yaml > SealedSecret-ElasticCredentials.yaml
Standaard

Als je geen SealedSecret controller hebt, kun je een Secret resource maken door het volgende commando uit te voeren:

# Maak een SealedSecret aan voor het admin elasticsearch wachtwoord kubectl -n elasticsearch create secret generic elastic-credentials \ --from-literal=ELASTIC_PASSWORD='STRONG-PASSWORD' \ --dry-run=client -o yaml > SealedSecret-ElasticCredentials.yaml
Standaard

Het bovenstaande commando maakt het yaml-bestand dat moet worden uitgerold naar het cluster.

3.4 Configmap aanmaken

De Configmap bevat het blok elasticsearch.yml met extra Elasticsearch-configuratie. We voegen onze Service DNS records toe aan onze discovery.seed_hosts, Elasticsearch zal zoeken naar extra nodes.

Dit blok wordt op de pod gemount onder de locatie /usr/share/elasticsearch/config/elasticsearch.yml.

apiVersion: v1soort: ConfigMapmetadata: naam:  elasticsearch-config namespace: elasticsearchdata: elasticsearch.yml: | cluster.name: "elasticsearch" bootstrap.memory_lock: false xpack.license.self_generated.type: basic network.host: "0.0.0.0" logger.org.elasticsearch.transport: error logger.org.elasticsearch.discovery: error discovery.seed_hosts: - elasticsearch-0.elasticsearch.svc.cluster.local:9300 - elasticsearch-1.elasticsearch.svc.cluster.local:9300 - elasticsearch-2.elasticsearch.svc.cluster.local:9300 cluster.initial_master_nodes: - elasticsearch-0 - elasticsearch-1 - elasticsearch-2 NODE_MASTER: "true" NODE_DATA: "true" AANTAL_OF_MASTERS: "3" AANTAL_OF_REPLICAS: "2"
YAML

Deze volume mount wordt ook gedeclareerd in statefulset.yaml:

        volumeMounts: - naam:  elasticsearch-data mountPath: /usr/share/elasticsearch/data - naam:  elasticsearch-yml mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml
YAML

Implementeer al uw yaml-bestanden en controleer of Elasticsearch zonder problemen draait. Als Elasticsearch niet goed draait, kunt u de containerlogboeken bekijken of de Pod/Statefulset beschrijven.

kubectl create -f ConfigMap.yaml -f Statefulset.yaml
Standaard

De volgende uitvoer zou moeten verschijnen:

configmap/elasticsearch-config created statefulset/elasticsearch created
Standaard

Laten we eens kijken of de elasticsearch statefulset met succes is ingezet.

kubectl get pod -n elasticsearch
Standaard

De volgende uitvoer zou moeten verschijnen:

NAMESPACE NAAM GEREED STATUS RESTARTS LEEFTIJD elasticsearch elasticsearch-0 1/1 Loopt 0 2m elasticsearch elasticsearch-1 1/1 Loopt 0 1m elasticsearch elasticsearch-2 1/1 Loopt 0 30sc
Standaard

3.5 De xpack-functie inschakelen

3.5.1 Certificaten genereren

Elasticsearch start niet op wanneer de beveiligingsfunctie is ingeschakeld zonder dat de beveiligingsconfiguratie is geconfigureerd!

Voordat we de beveiligingsfunctie kunnen inschakelen, moeten we certificaten aanmaken voor de Elasticsearch nodes. Elasticsearch nodes zullen veilig met elkaar communiceren.

Voer de volgende commando's uit in de elasticsearch container.

kubectl -n elasticsearch exec -ti elasticsearch-0 -- bash # Maak certificaten aan elasticsearch-certutil ca --out /tmp/elastic-stack-ca.p12 --pass '' elasticsearch-certutil cert --name security-master --dns security-master --ca /tmp/elastic-stack-ca.p12 --pass '' --ca-pass '' --out /tmp/elastic-certificates.p12 # kopieer certificaten naar lokale machine sudo kubectl cp elasticsearch/elasticsearch-0:/tmp/elastic-stack-ca.p12 ./elastic-stack-ca.p12 sudo kubectl cp elasticsearch/elasticsearch-0:/tmp/elastic-certificates.p12 ./elastic-certificates.p12 # Valideer en extraheer PEM openssl pkcs12 -nodes -passin pass:'' -in elastic-certificates.p12 -out elastic-certificate.pem
Standaard

Nadat we ons certificaat hebben gegenereerd en gekopieerd van de container naar onze lokale machine, maken we een SealedSecret van het PEM-bestand. Dit PEM-bestand koppelen we later aan de container.

# Maak een SealedSecret voor het P12-bestand kubectl -n elasticsearch create secret generic elastic-certificate-pem \ --from-file=elastic-certificates.p12 \ --dry-run=client -o yaml | ${KUBESEAL_BINARY} --cert ${KUBESEAL_CERT_PATH} --format yaml > SealedSecret-ElasticCertificates.yaml
Standaard

Als je geen SealedSecret controller hebt, kun je een Secret resource maken door het volgende commando uit te voeren.

# Maak SealedSecret voor het P12 bestand kubectl -n elasticsearch create secret generic elastic-certificate-pem \ --from-file=elastic-certificates.p12 \ --dry-run=client -o yaml > SealedSecret-ElasticCertificates.yaml
Standaard

Bovenstaand commando maakt het yaml-bestand aan dat naar het cluster moet worden uitgerold.

3.5.2 xpack beveiligingsfuncties inschakelen

Wanneer u met succes uw certificaat hebt aangemaakt en ingezet in het cluster, kunnen we nu de beveiligingsfuncties inschakelen.

Voeg de volgende configuratie toe aan de elasticsearch.yml configuratie in het ConfigMap.yaml bestand:

  xpack.license.self_generated.type: basic xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificaat 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: false 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
YAML

Door xpack.security.enabled in te stellen op true worden de xpack beveiligingsfuncties ingeschakeld. Maar alleen deze instelling inschakelen is niet genoeg. We moeten ook onze nieuw gegenereerde certificaten mounten en configureren.

Koppel het geheim dat de certificaten bevat aan de StatefulSet:

        volumeMounts: - naam:  elasticsearch-data mountPath: /usr/share/elasticsearch/data - naam:  elasticsearch-yml mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml - naam:  elastic-certificates mountPath: /usr/share/elasticsearch/config/certs ..... ..... volumes: - naam:  elasticsearch-yml configMap: naam:  elasticsearch-config items: - key: elasticsearch.yml path: elasticsearch.yml - naam:  elastic-certificates secret: secretName:  elastic-certificates
YAML

Sla de ConfigMap en Statefulset op en vervang deze. Wacht tot alle pods zijn afgesloten en opnieuw zijn gestart.
Als de pods niet automatisch herstart worden, schaal dan de statefulset af en schaal weer op:

kubectl -n elasticsearch scale statefulset elasticsearch --replicas 0 #wacht tot alle nodes zijn verwijderd kubectl -n elasticsearch scale statefulset elasticsearch --replicas 3
Standaard

Bekijk de logs en controleer of Elasticsearch goed draait. Als Elasticsearch niet goed draait, kunt u de containerlogs volgen of de Pod/Statefulset beschrijven.

Het bestand ConfigMap.yaml en Statefulset.yaml moet er dan zo uitzien.

3.5.3 Statefulset

apiVersion: apps/v1soort: StatefulSetmetadata: naam: elasticsearch namespace: elasticsearchspec: serviceName: elasticsearch replicas: 3 updateStrategy: type: OnDelete selector: matchLabels: app: elasticsearch template: metadata: labels: app: elasticsearch spec: securityContext: fsGroup: 1000 initContainers: - naam:  increase-vm-max-map image: busybox imagePullPolicy: IfNotPresent securityContext: privileged: true commando: [ "sysctl", "-w", "vm.max_map_count=262144" ] containers: - naam: elasticsearch image: "defined_in_kustomization" env: - naam: node.name valueFrom: fieldRef: fieldPath: metadata.name - naam: NODE_MASTER valueFrom: configMapKeyRef: naam:  elasticsearch-config key: NODE_MASTER - naam: NODE_DATA valueFrom: configMapKeyRef: naam:  elasticsearch-config key: NODE_DATA - naam: NUMBER_OF_MASTERS valueVan: configMapKeyRef: naam:  elasticsearch-config key: NUMBER_OF_MASTERS - naam: NUMBER_OF_REPLICAS waardeVan: configMapKeyRef: naam:  elasticsearch-config key: NUMBER_OF_REPLICAS - name: ES_JAVA_OPTS valueFrom: configMapKeyRef: name:  elasticsearch-config key: ES_JAVA_OPTS - name: ES_PORT value: "9200" - naam: ELASTIC_PASSWORD waardeVan: secretKeyRef: naam:  elastic-credentials sleutel: ELASTIC_PASSWORD poorten: - containerPort: 9200 naam: rest protocol: TCP - containerPort: 9300 naam: transport protocol: TCP volumeMounts: - naam:  elasticsearch-data mountPath: /usr/share/elasticsearch/data - naam:  elasticsearch-yml mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml - naam:  elastic-certificates mountPath: /usr/share/elasticsearch/config/certs resources: requests: cpu: "1000m" memory: "2Gi" limieten: cpu: "1000m" geheugen: "2Gi" volumes: - naam:  elasticsearch-yml configMap: naam:  elasticsearch-config items: - key: elasticsearch.yml path: elasticsearch.yml - naam:  elastic-certificates secret: secretName:  elastic-certificates volumeClaimTemplates: - metadata: naam:  elasticsearch-data annotations: volume.beta.kubernetes.io/storage-class: gp3 spec: accessModes: [ "ReadWriteOnce" ] bronnen: requests: storage: 50Gi
YAML
3.5.3.1 readinessProbe

Als je readinessprobe wilt toevoegen, voeg dan het volgende toe aan je Statefulset.yaml:

readinessProbe: exec: command: - /bin/bash - -c - |-health=$(curl -s -o/dev/null -uelastic:${ELASTIC_PASSWORD} --write-out"%{http_code}" localhost:9200/_cluster/health?local=true) if [[ ${health} -ne200]]; then exit 1; fi initialDelaySeconds: 5
YAML

3.5.4 ConfigMap

apiVersie: v1soort: ConfigMapmetadata: naam:  elasticsearch-config namespace: elasticsearchdata: elasticsearch.yml: | cluster.name: "elasticsearch" bootstrap.memory_lock: false xpack.license.self_generated.type: basic xpack.monitoring.collection.enabled: true xpack.security.http.ssl.enabled: false 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.truststore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 xpack.security.http.ssl.keystore.path: /usr/share/elasticsearch/config/certs/elastic-certificates.p12 network.host: "0.0.0.0" logger.org.elasticsearch.transport: fout logger.org.elasticsearch.discovery: fout discovery.seed_hosts: - elasticsearch-0.elasticsearch.svc.cluster.local:9300 - elasticsearch-1.elasticsearch.svc.cluster.local:9300 - elasticsearch-2.elasticsearch.svc.cluster.local:9300 cluster.initial_master_nodes: - elasticsearch-0 - elasticsearch-1 - elasticsearch-2 NODE_MASTER: "true" NODE_DATA: "true" AANTAL_OF_MASTERS: "3" AANTAL_OF_REPLICAS: "2" ES_JAVA_OPTS: "-Djava.net.preferIPv4Stack=true -Xms1750m -Xmx1750m"
YAML

4. Fluentd DaemonSet implementeren

Nu is het tijd om containerlogs naar Elasticsearch te sturen. We hebben onze fluentD namespace al aangemaakt.

U kunt meer informatie over FluentD vinden door op de volgende link te klikken: https://www.fluentd.org/

4.1 ServiceAccount aanmaken

Laten we opnieuw beginnen met het aanmaken van de RBAC resources. We zullen de FluentD ServiceAccount voldoende toestemming geven om de logs van het cluster en de staartcontainer te onderzoeken.

apiVersion: v1soort: ServiceAccountmetadata: naam: fluentd namespace: fluentd labels: app: fluentd
YAML

Vervolgens ClusterRole en deze binden aan de fluentd ServiceAccount.

apiVersion: rbac.authorization.k8s.io/v1soort: ClusterRolemetadata: name: fluentd labels: app: fluentdrules: - apiGroups: - "" resources: - pods - namespaces verbs: - get - list - watch
YAML

Bind het nu aan de ServiceAccount.

soort: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: fluentdroleRef: kind: ClusterRole naam: fluentd apiGroup: rbac.authorization.k8s.iosubjecten: - soort: ServiceAccount naam: fluentd namespace: fluentd
YAML

4.2 ConfigMap aanmaken

apiVersion: v1soort: ConfigMapmetadata: naam:  fluentd-config namespace: fluentddata: fluent.conf: | <match fluent.**> # this tells fluentd to not output its log on stdout @type null </match> # here we read the logs from Docker's containers and parse them <source> @type tail path /var/log/containers/*.log pos_file /var/log/app.log.pos tag kubernetes.* read_from_head true <parse> @type json time_format %Y-%m-%dT%H:%M:%S.%NZ </parse> </source> # we gebruiken kubernetes metadata plugin om metadata toe te voegen aan het log <filter kubernetes.**> @type kubernetes_metadata </filter> # we sturen de logs naar Elasticsearch <match **> @type elasticsearch_dynamic @log_level info include_tag_key true host "#{ENV['FLUENT_ELASTICSEARCH_HOST']}" port "#{ENV['FLUENT_ELASTICSEARCH_PORT']}" user "#{ENV['FLUENT_ELASTICSEARCH_USER']}" password "#{ENV['FLUENT_ELASTICSEARCH_PASSWORD']}" scheme "#{ENV['FLUENT_ELASTICSEARCH_SCHEME'] || 'http'}" ssl_verify "#{ENV['FLUENT_ELASTICSEARCH_SSL_VERIFY'] || 'true'}" reload_connections true logstash_format true logstash_prefix "#{ENV['K8S_NODE_NAME']}-${record['kubernetes']['pod_name']}" <buffer> @type bestandspad /var/log/fluentd-buffers/kubernetes.system.buffer flush_mode interval retry_type exponential_backoff flush_thread_count 2 flush_interval 5s retry_forever true retry_max_interval 30 chunk_limit_size 2M queue_limit_length 32 overflow_action block </buffer> </match> K8S_NODE_NAME: "efk-stack" FLUENT_ELASTICSEARCH_USER: "elastic" NUMBER_OF_REPLICAS: "2" FLUENT_ELASTICSEARCH_HOST: "elasticsearch.elasticsearch.svc.cluster.local"
YAML

4.3 DaemonSet aanmaken

apiVersion: apps/v1soort: DaemonSetmetadata: naam: fluentd namespace: fluentd labels: app: fluentdspec: selector: matchLabels: app: fluentd template: metadata: labels: app: fluentd spec: serviceAccountName: fluentd containers: - naam: fluentd image: "defined_in_kustomization" env: - name: FLUENT_ELASTICSEARCH_HOST valueFrom: configMapKeyRef: name:  fluentd-config key: FLUENT_ELASTICSEARCH_HOST - name: FLUENT_ELASTICSEARCH_PORT value: "9200" - naam: FLUENT_ELASTICSEARCH_SCHEME waarde: "http" - name: FLUENTD_SYSTEMD_CONF value: disable - name: K8S_NODE_NAME valueFrom: configMapKeyRef: name:  fluentd-config key: K8S_NODE_NAME - naam: FLUENT_ELASTICSEARCH_USER waardeVan: configMapKeyRef: naam:  fluentd-config key: FLUENT_ELASTICSEARCH_USER - naam: FLUENT_ELASTICSEARCH_PASSWORD waardeVan: secretKeyRef: naam:  fluentd-credentials sleutel: FLUENT_ELASTICSEARCH_PASSWORD bronnen: limieten: geheugen: 512Mi requests: cpu: 100m geheugen: 200Mi volumeMounts: - naam: varlog mountPath: /var/log - naam: varlibdockercontainers mountPath: /var/lib/docker/containers readOnly: true - naam:  fluentd-config mountPath: /fluentd/etc terminationGracePeriodSeconds: 30 volumes: - naam: varlog hostPath: path: /var/log - naam: varlibdockercontainers hostPath: path: /var/lib/docker/containers - naam:  fluentd-config configMap: naam:  fluentd-config items: - sleutel: fluent.conf pad: fluent.conf
YAML

Het FLUENT_ELASTICSEARCH_PASSWORD is hetzelfde wachtwoord dat we hebben gedefinieerd in de Elasticsearch-configuratie(ELASTIC_PASSWORD).

Definieer de omgevingsvariabelen in het bestand ConfigMap.yaml, we definiëren ook enkele aangepaste Fluentd-configuraties. Deze configuratie wordt gemount op de Fluentd-container.

Implementeer al uw yaml-bestanden en controleer of Fluentd zonder problemen draait. Als Fluentd niet goed draait, kunt u de containerlogboeken bekijken of de Pod/DaemonSet beschrijven.

5. Deployment van Kibana

Nu hebben we opslag (Elasticsearch) en gegevensstroom (Fluentd). Vervolgens hebben we Kibana nodig om de gegevens te bekijken / bewerken / ....

De configuratie van Kibana is bijna hetzelfde als die van Elasticsearch en Fluentd. We definiëren enkele omgevingsvariabelen om onze Kibana-configuratie te maken.

Deze configuraties zijn voornamelijk

  • gebruikersnaam en wachtwoord van de kibana-gebruiker,
  • verbindingsinstellingen met Elasticsearch,
  • hetzelfde Elasticsearch-certificaat is geïnstalleerd

5.1 Kibana-inloggegevens aanmaken

Kibana gebruikersnaam en wachtwoord

Wanneer we Kibana starten, is de eerste vraag die Kibana ons stelt: "Wat is de gebruikersnaam en het wachtwoord van de Kibana-gebruiker". De gebruikersnaam is kibana_system. Het wachtwoord kan worden opgevraagd vanuit de Elasticsearch-container.

Ga naar een van de Elasticsearch-containers en voer het volgende commando uit:

kubectl -n elasticsearch exec -ti elasticsearch-0 -- bash #Dit zal een willekeurige string genereren. Sla het wachtwoord op! ./bin/elasticsearch-reset-password -u kibana_system
Standaard

SealedSecret aanmaken en implementeren met het opgegeven wachtwoord:

kubectl -n kibana create secret generic kibana-credentials \ --from-literal=ELASTICSEARCH_PASSWORD='XXXXX' \ --dry-run=client -o yaml | ${KUBESEAL_BINARY} --cert ${KUBESEAL_CERT_PATH} --format yaml > SealedSecret-KibanaCredentials.yaml
Standaard

Als je geen SealedSecret controller hebt, kun je een Secret resource maken door het volgende commando uit te voeren.

kubectl -n kibana create secret generic kibana-credentials \ --from-literal=ELASTICSEARCH_PASSWORD='XXXXX' \ --dry-run=client -o yaml > SealedSecret-KibanaCredentials.yaml
Standaard

Het bovenstaande commando maakt het yaml-bestand dat moet worden uitgerold naar het cluster.

5.2 Service aanmaken

Nu is het tijd om de Service resource aan te maken. Kibana zal toegankelijk zijn op poort 5601 en het label app: kibana gebruiken om de doel-Pods van de service te selecteren.

apiVersion: v1soort: Servicemetadata: naam: kibana namespace: kibana labels: app: kibanaspec: selector: app: kibana poorten: - naam: http poort: 80 targetPort: 5601
YAML

5.3 Deployment aanmaken

Zorg ervoor dat het ELASTICSEARCH_PASSWORD is gedefinieerd in de omgevingsvariabele en het juiste Secret leest.

We moeten ook een nieuw geheim aanmaken van hetzelfde PEM-certificaat dat we in de eerste stap hebben gegenereerd om later op de container te mounten.

# Maak SealedSecret aan voor het P12 bestand kubectl -n kibana create secret generic elastic-certificate-pem \ --from-file=elastic-certificates.p12 \ --dry-run=client -o yaml | ${KUBESEAL_BINARY} --cert ${KUBESEAL_CERT_PATH} --format yaml > SealedSecret-KibanaCertificates.yaml
Standaard

Als je geen SealedSecret controller hebt, kun je een Secret resource maken door het volgende commando uit te voeren.

# Maak SealedSecret voor het P12 bestand kubectl -n kibana create secret generic elastic-certificate-pem \ --from-file=elastic-certificates.p12 \ --dry-run=client -o yaml > SealedSecret-KibanaCertificates.yaml
Standaard

Het bovenstaande commando maakt het yaml-bestand dat moet worden uitgerold naar het cluster.

apiVersion: apps/v1soort: Deploymentmetadata: naam: kibana namespace: kibana labels: app: kibanaspec: replicas: 1 selector: matchLabels: app: kibana template: metadata: labels: app: kibana spec: affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In waarden: - kibana topologyKey: kubernetes.io/hostname preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - kibana topologyKey: topology.kubernetes.io/zone containers: - name: kibana image: docker.elastic.co/kibana/kibana:8.3.2 resources: limits: cpu: 1000m requests: cpu: 100m env: - name: ELASTICSEARCH_HOSTS valueFrom: configMapKeyRef: name:  kibana-config key: ELASTICSEARCH_HOSTS - naam: SERVER_NAME valueFrom: configMapKeyRef: naam:  kibana-config key: SERVER_NAME - naam: ELASTICSEARCH_USERNAME valueVan: configMapKeyRef: naam:  kibana-config key: ELASTICSEARCH_USERNAME - naam: ELASTICSEARCH_PASSWORD waardeVan: secretKeyRef:             naam:  kibana-credentials sleutel: ELASTICSEARCH_PASSWORD poorten: - containerPort: 5601 naam: http protocol: TCP volumeMounts: - naam:  kibana-certificates mountPath: /usr/share/kibana/config/certs - naam:  kibana-yml mountPath: /usr/share/kibana/config/kibana.yml subPath: kibana.yml volumes: - name:  kibana-certificates secret: secretName:  kibana-certificates - name:  kibana-yml configMap: name:  kibana-config items: - key: kibana.yml path: kibana.yml
YAML

5.4 ConfigMap aanmaken

apiVersie: v1soort: ConfigMapmetadata: name:  kibana-config namespace: kibanadata: kibana.yml: # # DIT IS EEN AUTO-GENERATED BESTAND ** # Standaard Kibana configuratie voor docker target server.host: "0.0.0.0" server.shutdownTimeout: "5s" elasticsearch.hosts: [ "http://elasticsearch:9200" ] monitoring.ui.container.elasticsearch.enabled: true xpack.encryptedSavedObjects.encryptionKey: f9cd92d3834129433fb0404740b5e89c xpack.reporting.encryptionKey: e3de4fcf3fb5e6f973ce024121ead576 xpack.security.encryptionKey: 4afebd157537e0f1b2c0b8deddff6b68 SERVER_NAME: "kibana.example.com" ELASTICSEARCH_HOSTS: " http://elasticsearch.elasticsearch.svc.cluster.local:9200" ELASTICSEARCH_USERNAME: "kibana_systeem"
YAML

Implementeer alle configuraties in de repository en volg de logs van Kibana.

En de installatie is klaar!

U kunt nu uw indexen toevoegen, gebruikers configureren, rollen configureren, ... en uw logs monitoren!

6. Conclusie

In deze Kubernetes tutorial hebben we laten zien hoe je Elasticsearch, Fluentd en Kibana (EFK Stack) kunt instellen en configureren op een Kubernetes cluster.

Centraliseer en maak het leven van de ontwikkelaars gemakkelijk door containerlogs bloot te leggen in één gecentraliseerde loginfrastructuur!

Als je deze tutorial leuk vond en in de toekomst meer informatie over deze onderwerpen wilt, volg ons dan op LinkedIn!


Ugur Akkar
Ugur Akkar
Solution Engineer, ACA Group
Contact us

Want to dive deeper into this topic?

Get in touch with our experts today. They are happy to help!

ACA mug mok koffie tas
Contact us

Want to dive deeper into this topic?

Get in touch with our experts today. They are happy to help!

ACA mug mok koffie tas
Contact us

Want to dive deeper into this topic?

Get in touch with our experts today. They are happy to help!

ACA mug mok koffie tas
Contact us

Want to dive deeper into this topic?

Get in touch with our experts today. They are happy to help!

ACA mug mok koffie tas