Openshift Container Platform‘ u Merkezi ELK Entegrasyonu

Ferhat Sanuc
Turk Telekom Bulut Teknolojileri
5 min readJan 2, 2022

Bildiğiniz gibi Openshift Container Platformu bir CaaS (Container as a Service) çözümü değil bir PaaS (Platform as a Service) çözümüdür. Container tabanlı uygulamalarımızı çalıştırmamızı sağlayan ve bu noktada uygulama yaşam döngüsü süreçlerine katkı sunan bir çok hizmeti barındıran bir Platform çözümüdür.

Openshift Container Platform’ u üzerinde bir Loglama yapısı bulunmaktadır. openshift-logging namespace’i içerisinde kurulu olan EFK (Elasticsearch, Fluentd, Kibana) yapısı ile platform üzerinde çalışan container’ ların loglarını saklamayı ve ihtiyaç durumunda da ulaşabilmeyi sağlamaktadır. Ancak kapasite planlaması veya merkezi çözüm ihtiyaçları gibi sebepler ile container’ ların loglarını platformun dışarısında bir yapıya yönlendirme ihtiyacı olabilmektedir. Bu gereksinim durumunda birden fazla yöntem mümkündür.

İlk olarak Openshift Logging Operatorü’ nün sunduğu Log Forwarding yapısını kullanabilirsiniz. Bu sayede Openshift üzerine ayrı bir ürün kurmadan mevcut loglama yapısı ile dış ortama container ve audit loglarını yönlendirebilirsiniz. Ancak bu yapınında ihtiyaçlarınızı karşılamadığı durumlar olabilir. Bu sebeple alternatif çözümler arayabilirsiniz. Bu yazıda bu alternatif yöntemlerden sadece biri olan filebeat ile container loglarının platform dışında bulunan bir elasticsearch ortamına yönlendirmeyi detaylı olarak anlatmaya çalışacağız.

İlk olarak neden log forwarding kullanarak fluentd üzerinden logları göndermedik bu detayı belirteyim. Openshift 4.x versiyonun bulunan Loglama yapısında elasticsearch üzerinde üç tip index oluşmaktadır. Bunlar app-*, infra-* ve audit-* şeklindedir. Yönettiğiniz birden fazla Openshift ortamınız varsa tüm bu ortamların loglarını tek bir elasticsearch e yönlendirdiğinizde namespace ve cluster bazlı indexleri ayırma ihtiyacınız olacaktır. Mevcut log forwarding ile tüm ortamlardan index isimleri aynı geldiği için bunu yönetmek için alternatif çözümler arama ihtiyacı doğmuştur. Bu noktada da filebeat ile ilerlemeye karar verdik.

Kurulum adımlarına geçmeden aşağıdaki görselde bulunan mimariyi inceleyebilirsiniz.

Örnek bir Elasticsearch Cluster ve Çevre Bileşenleri

Openshift ortamından logları filebeat ile metric’ leri ise metricbeat ile toplayarak dış ortama yönlendirebiliriz. Bu yazıda filebeat ile container loglarının yönlendirimesine değineceğiz. Burada iki alternatifden bahsedeceğiz. Filebeat ile logstash’ e logları yönlendirerek burada logstash pipeline’ da belirttiğimiz konfigurasyona göre elasticsearch’ e logları yönlendirmeyi ve filebeat üzerinden doğrudan elasticsearch’ e logları yönlendirmeyi ele alacağız.

İlk olarak filebeat ve metricbeat kurulumunu gerçekleştireceğimiz namespace’ i oluşturuyoruz.

# oc new-project central-logging --display-name=”Central Logging Project”

Filebeat kurulumu için aşağıdaki yaml içeriğini çalıştırabilirsiniz. filebeat.yml dan sonraki içeriği bir dosyaya kopyalarak oc create ile filebeat kurulumunu gerçekleştirebilirsiniz.

# oc create -f filebeat.ymlfilebeat.yml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: central-logging
labels:
k8s-app: filebeat
data:
filebeat.yml: >-
filebeat.inputs:
- type: container
paths:
- /var/log/containers/*.log
processors:
- add_kubernetes_metadata:
host: ${NODE_NAME}
matchers:
- logs_path:
logs_path: "/var/log/containers/"
- add_tags:
tags: [ocpcluster1]
processors:
- add_cloud_metadata:
- add_host_metadata:
cloud.id: ${ELASTIC_CLOUD_ID}cloud.auth: ${ELASTIC_CLOUD_AUTH}output.logstash:
hosts: ['logstash1:5044','logstash2:5044']
loadbalance: true
username: [user]
password: [password]
ssl.certificate_authorities: ["/etc/pki/client/ca.pem"]
ssl.certificate: "/etc/pki/client/cert.pem"
ssl.key: "/etc/pki/client/cert.key"
ssl.verification_mode: none

logging.level: warning
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat
namespace: central-logging
labels:
k8s-app: filebeat
spec:
selector:
matchLabels:
k8s-app: filebeat
template:
metadata:
labels:
k8s-app: filebeat
spec:
serviceAccountName: filebeat
terminationGracePeriodSeconds: 30
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
tolerations:
- key: node.ocs.openshift.io/storage
value: 'true'
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
- key: node.kubernetes.io/disk-pressure
operator: Exists
effect: NoSchedule
containers:
- name: filebeat
image: docker.elastic.co/beats/filebeat:7.12.0
args: [
"-c", "/etc/filebeat.yml",
"-e",
]
env:
- name: ELASTIC_CLOUD_ID
value:
- name: ELASTIC_CLOUD_AUTH
value:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
securityContext:
runAsUser: 0
# If using Red Hat OpenShift uncomment this:
privileged: true
resources:
limits:
memory: 400Mi
requests:
cpu: 100m
memory: 350Mi
volumeMounts:
- name: config
mountPath: /etc/filebeat.yml
readOnly: true
subPath: filebeat.yml
- name: data
mountPath: /usr/share/filebeat/data
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
- name: varlog
mountPath: /var/log
readOnly: true
- name: filebeat-cert
mountPath: /etc/pki/client/
readOnly: true
volumes:
- name: config
configMap:
defaultMode: 0640
name: filebeat-config
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
- name: varlog
hostPath:
path: /var/log
# data folder stores a registry of read status for all files, so we don't send everything again on a Filebeat pod restart
- name: data
hostPath:
# When filebeat runs as non-root user, this directory needs to be writable by group (g+w).
path: /var/lib/filebeat-data
type: DirectoryOrCreate
- name: filebeat-cert
secret:
defaultMode: 0640
secretName: filebeat
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: filebeat
subjects:
- kind: ServiceAccount
name: filebeat
namespace: central-logging
roleRef:
kind: ClusterRole
name: filebeat
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: filebeat
labels:
k8s-app: filebeat
rules:
- verbs:
- get
- watch
- list
apiGroups:
- ''
resources:
- namespaces
- pods
- nodes
- verbs:
- get
- list
- watch
apiGroups:
- apps
resources:
- replicasets
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: filebeat
namespace: central-logging
labels:
k8s-app: filebeat
---

Yukarıdaki konfigurasyonda filebeat üzerinden loglar logstash’ e ssl olarak yönlendirilmiştir. Burada dışarıdaki ortamınız ssl değil ise aşağıdaki satırları kaldırabilirsiniz.

ssl.certificate_authorities: ["/etc/pki/client/ca.pem"]
ssl.certificate: "/etc/pki/client/cert.pem"
ssl.key: "/etc/pki/client/cert.key"
ssl.verification_mode: none

Ancak ssl ile ilerliyorsanız mevcut logstash/elasticsearch ortamınızın sertifikalarını aşağıdaki gibi secret içerisine tanımlamanız gerekmektedir.

# oc create secret generic filebeat --from-file=ca.pem=./ca.pem --from-file=cert.key=./cert.key --from-file=cert.pem=./cert.pemveya aşağıdaki yaml içerisine sertifika bilgilerini ekleyerek de oluşturabilirsiniz.
---
kind: Secret
apiVersion: v1
metadata:
name: filebeat
namespace: central-logging
data:
ca.pem: [base64 formatında]
cert.key: [base64 formatında]
cert.pem: [base64 formatında]
type: Opaque

Son olarak da tüm nodelarda container’ ların loglarını toplayabilmesi için service account’ a yetki vermemiz gerekmektedir.

# oc adm policy add-scc-to-user privileged system:serviceaccount:central-logging:filebeat

Bu adımlar sonunda filebeat uygulamasını deamonset olarak namespace’ imize kurmuş olduk ve container’ ların loglarını dışarıdaki logstash ortamına yönlendirmektedir. Bu noktada Openshift ortamındaki adımlarımız tamamlanmıştır.

Elasticsearch’ e logları yönlendirmek için son bir konfigurasyon Logstash üzerinde yapılacaktır. Logstash üzerinde pipeline oluşturarak Openshift ortamlarından gelen logları istediğimiz standartda index ismi ile Elasticsearch ortamına yönlendireceğiz.

Bunun için aşağıdaki gibi Logstash üzerinde pipeline oluşturabilirsiniz.

input {
beats {
port => 5044
type => container
ssl => true
ssl_certificate_authorities => ["/etc/logstash/certs/ca.crt"]
ssl_key => '/etc/logstash/certs/logstashca.pem'
ssl_certificate => '/etc/logstash/certs/wilcardpaasturktelekomcomtr.crt'
ssl_verify_mode => "none"
}
}
output {
if "ocpcluster1" in [tags]{
elasticsearch {
hosts => ["https://elasticsearch1:9200","https://elasticsearch2:9200","https://elasticsearch3:9200"]
index => "ocpcluster1-%{[kubernetes][namespace]}"
user => [user]
password => [password]
ssl => true
ssl_certificate_verification => false
cacert => '/etc/logstash/certs/ca.crt'
}
}

Yukarıdaki pipeline tanımı ile birlikte Kibana üzerinden index’ leriniz görüntüleyebilirsiniz.

Filebeat kurulum ve entegrasyonumuzu tamamlamış olduk. Bu bölümde sadece detay birkaç bilgi veriyor olacağız.

Configmap’ de aşağıdaki gibi tag girerek logstash üzerinde farklı cluster’ lardan gelen logları ayrıştırmayı sağlıyoruz. Bu gelen tag’ e göre yukarıdaki gibi Pipeline’ da if koşulu ile her ortamdan gelen index’ leri elasticsearch üzerinde farklı index’ lere yazmayı sağlıyoruz.

- add_tags:
tags: [ocpcluster1]

Filebeat Pod’ ları çok fazla log üretiyorsa aşağıdaki gibi configmap içerisinde log level’ ını yönetebilirsiniz.

logging.level: warning

Eğer yapınızda logstash kullanmak istemiyor ve direk olarak elasticsearch’ e logları göndermek istiyorsanız configmap içerisinde output.logstash bölümünü kaldırarak aşağıdaki output.elasticsearch bölümünü ekleyebilirsiniz.

output.elasticsearch:
hosts: ["https://elasticsearch1:9200"]
username: [ELASTICSEARCH_USERNAME]
password: [ELASTICSEARCH_PASSWORD]
ssl.certificate_authorities: ["/etc/pki/client/ca.pem"]
ssl.certificate: "/etc/pki/client/cert.pem"
ssl.key: "/etc/pki/client/cert.key"
ssl.verification_mode: none
index: "ocpcluster1-%{[kubernetes.namespace]:filebeat}"
setup.template.name: "ocpcluster1"
setup.template.pattern: "ocpcluster1-*"
setup.dashboards.index: "ocpcluster1-*"
setup.dashboards.enabled: false
setup.ilm.enabled: false

Eğer platformunuzda node’ larınızda taint kullanıyorsanız bu node’ lar üzerinde filebeat pod’ larının kalkması için aşağıdaki gibi toleration tanımlamalısınız.

tolerations:
- key: node.ocs.openshift.io/storage
value: 'true'
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
- key: node.kubernetes.io/disk-pressure
operator: Exists
effect: NoSchedule

Bu yazıda filebeat üzerinden logların dış ortama gönderilmesini detaylı olarak ele aldık. Bir sonraki yazıda metricbeat ile pod ve node’ ların metriklerinin dış ortama yönlendirilmesine değineceğiz.

--

--