
.png?auto=compress,webp&upscale=true&width=610&height=488&name=hubspot%20covers%20(4).png)
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
FluentD naamruimte:
soort: NaamruimteapiVersie: v1metadata: naam: fluentd groep: fluentd
Kibana naamruimte:
soort: NamespaceapiVersion: v1metadata: name: fluentd group: fluentd
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
De volgende uitvoer zou moeten verschijnen:
namespace/elasticsearch created namespace/kibana created namespace/fluentd created
We kunnen valideren of de namespaces met succes zijn aangemaakt door het volgende commando uit te voeren:
kubectl get namespaces
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
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
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"
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: ""
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
Laten we onze yaml-bestanden inzetten op het cluster:
kubectl create -f Service.yaml -f ServiceAccount.yaml -f ClusterRole.yaml -f ClusterRoleBinding.yaml
Laten we nu eens kijken of de elasticsearch Service met succes is ingezet:
kubectl get services -n elasticsearch
De volgende uitvoer zou moeten verschijnen:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch ClusterIP None <none> 9200/TCP,9300/TCP 1m
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
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
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
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"
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
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
De volgende uitvoer zou moeten verschijnen:
configmap/elasticsearch-config created statefulset/elasticsearch created
Laten we eens kijken of de elasticsearch statefulset met succes is ingezet.
kubectl get pod -n elasticsearch
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
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
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
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
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
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
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
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
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
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"
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
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
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
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"
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
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
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
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
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
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
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
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
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"
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!

What others have also read


CloudBrew is altijd een hoogtepunt op onze kalender geweest, maar de editie van 2025 voelde anders. Misschien lag het aan de timing. Slechts een maand eerder, in november 2025, opende de Azure Belgium Central-regio eindelijk haar deuren. ACA opereert
Lees verder

Een betere uptime, lagere kosten en vendor lock-in vermijden. Dat zijn drie van de redenen waarom onze klanten kiezen voor een multicloud-strategie. Onze Cloud project manager Roel Van Steenberghe legt uit wat zo’n strategie precies inhoudt en wat de
Lees verder

In de complexe wereld van moderne softwareontwikkeling worden bedrijven geconfronteerd met de uitdaging om verschillende applicaties die door verschillende teams worden ontwikkeld en beheerd, naadloos te integreren. De Service Mesh is van onschatbare
Lees verderWant to dive deeper into this topic?
Get in touch with our experts today. They are happy to help!

Want to dive deeper into this topic?
Get in touch with our experts today. They are happy to help!

Want to dive deeper into this topic?
Get in touch with our experts today. They are happy to help!

Want to dive deeper into this topic?
Get in touch with our experts today. They are happy to help!


