fluentd를 활용해 kubernetes 로그를 elasticsearch에 저장하고 kibana로 표출 해보자!
kubernetes를 셋팅을 하고 다음으로 해야 할일은 모니터링이다.
그 작업의 기초가 되는일이 바로 로깅을 쌓는 일이다.
모든 컨테이너의 로그들을 모아서 한 곳에서 확인할 수 있도록 구성했다.
각 컨테이너에서 로그를 가져오는 것은 fluentd를 이용했다.
fluentd에서 elasticsearch로 데이터를 적재 하도록 설정하였고, kibana를 통해서 해당 데이터를 표출했다.
kubernetes <-로그수집- fluentd -데이터 적재-> elasticsearch <-표출- kibana
구축 순서
elasticsearch 구성
kubernetes의 오브젝트를 생성하기 위한 yaml 파일을 다음과 같이 생성한다.
# elastic.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: elasticsearch
labels:
app: elasticsearch
spec:
replicas: 1
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
spec:
containers:
- name: elasticsearch
image: elastic/elasticsearch:6.8.6
env:
- name: discovery.type
value: "single-node"
ports:
- containerPort: 9200
- containerPort: 9300
---
apiVersion: v1
kind: Service
metadata:
labels:
app: elasticsearch
name: elasticsearch-svc
namespace: default
spec:
ports:
- name: elasticsearch-rest
nodePort: 30482
port: 9200
protocol: TCP
targetPort: 9200
- name: elasticsearch-nodecom
nodePort: 30930
port: 9300
protocol: TCP
targetPort: 9300
selector:
app: elasticsearch
type: NodePort
kubectl
명령어를 이용해서 오브젝트를 kubernetes에 생성한다.
$ kbuectl apply -f elastic.yml
deployment.apps/elasticsearch created
service/elasticsearch-svc created
설정된 노드포트를 통해서 서비스를 확인할 수 있다.
http://${kubernetes_host}:30842/
kibana 구성
kubernetes의 오브젝트를 생성하기 위한 yaml 파일을 다음과 같이 생성한다.
# kibana.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: kibana
labels:
app: kibana
spec:
replicas: 1
selector:
matchLabels:
app: kibana
template:
metadata:
labels:
app: kibana
spec:
containers:
- name: kibana
image: elastic/kibana:6.8.6
env:
- name: SERVER_NAME
value: "kibana.kubenetes.example.com"
- name: ELASTICSEARCH_URL
value: "http://elasticsearch-svc.default.svc.cluster.local:9200"
ports:
- containerPort: 5601
---
apiVersion: v1
kind: Service
metadata:
labels:
app: kibana
name: kibana-svc
namespace: default
spec:
ports:
- nodePort: 30920
port: 5601
protocol: TCP
targetPort: 5601
selector:
app: kibana
type: NodePort
연결하는 elasticsearch 주소는 http://elasticsearch-svc.default.svc.cluster.local:9200
이다. kubectl
명령어를 이용해서 오브젝트를 kubernetes에 생성한다.
$ kbuectl apply -f kibana.yml
deployment.apps/kibana created
service/kibana-svc created
설정된 노드포트를 통해서 서비스를 확인할 수 있다.
fluentd 구성
kubernetes의 오브젝트를 생성하기 위한 yaml 파일을 다음과 같이 생성한다.
# fluentd.yml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: fluentd
name: fluentd
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: fluentd
rules:
- apiGroups:
- ""
resources:
- "namespaces"
- "pods"
verbs:
- "list"
- "get"
- "watch"
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: fluentd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: fluentd
subjects:
- kind: ServiceAccount
name: fluentd
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-system
labels:
k8s-app: fluentd-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
k8s-app: fluentd-logging
template:
metadata:
labels:
k8s-app: fluentd-logging
version: v1
kubernetes.io/cluster-service: "true"
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch-svc.default.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
- name: FLUENTD_SYSTEMD_CONF
value: "disable"
- name: FLUENT_UID
value: "0"
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
위의 설정에서 보면 /var/log를 모두 로그를 가져오며 가져온 데이터는 http://elasticsearch-svc.default.svc.cluster.local:9200
에 적재 한다.
kubectl
명령어를 이용해서 오브젝트를 kubernetes에 생성한다.
$ kbuectl apply -f fluentd.yml
serviceaccount/fluentd created
clusterrole.rbac.authorization.k8s.io/fluentd created
clusterrolebinding.rbac.authorization.k8s.io/fluentd created
daemonset.apps/fluentd created
설치시 오류 발생에 따른 해결책
unable to recognize “filebeat-kubernetes.yaml”: no matches for kind “DaemonSet” in version “extensions/v1beta1” 과 같은 오류가 발생한 이유는 apiVersion
이 extensions/v1beta1을 사용하지 말고 apps/v1을 사용하도록 되어 있다.
다음과 같은 오류가 발생할 경우,
2018-11-26 23:19:44 +0000 [warn]: suppressed same stacktrace
2018-11-26 23:19:50 +0000 [info]: stats - namespace_cache_size: 3, pod_cache_size: 6, namespace_cache_api_updates: 15, pod_cache_api_updates: 15, id_cache_miss: 15
2018-11-26 23:20:14 +0000 [warn]: temporarily failed to flush the buffer. next_retry=2018-11-26 23:20:44 +0000 error_class="MultiJson::AdapterError" error="Did not recognize your adapter specification (cannot load such file -- bigdecimal)." plugin_id="out_es"
debian 계열의 이미지를 사용하면 된다.
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
Did not recognize your adapter specification #230
설치가 완료되고 나면, 각 worker node에서 기동하는 것을 확인 할 수 있다.
kibana 설정
Management => kibana => Index Patterns => Create Index Pattern => "logstash-*" 추가
위와 같이 처리 하면 다음과 같은 결과를 확인 할 수 있다.
마치며
한땀 한땀 설치 kubernetes의 오부젝트에 대하여 더 많이 이해하게 되었다.
데이터 적재의 형태나, node의 error 로그 적재 등은 좀더 확인해봐야겠다.