Prometheus는 CNCF의 몇 안되는 graduate 프로젝트 중 하나인 시계열 모니터링 시스템입니다.
이런 Prometheus는 일반적인 VM 환경에서도 사용할 수 있지만 Kuberenetes에서 사용하는 MSA 구성에도 사용할 수 있다는 장점 이 있는데요.
하지만 Kubernetes 환경은 비영구적이고 임시적인 Pod를 기반으로 이루어져 있기 때문에 Prometheus를 구성하는 요소와 Prometheus의 메트릭 수집 대상들을 관리하기가 힘들다는 특징이 있습니다.
게다가 Prometheus는 시스템 내부의 yaml Config 파일을 기준으로 설정을 유지하는데, 이는 컨테이너 내부의 파일을 변경하기가 번거로운 Kubernetes 환경에서 Prometheus 관리를 더 힘들게 하는 원인이었습니다.
그래서 이 같은 문제를 해결하고자 나온 것이 Prometheus Operator입니다.
Prometheus Operator는 Kubernetes 환경에서 Prometheus 관리를 자동화해 간단하게 구성할 수 있도록 도와주는 도구입니다.
특히 기존 Kubernetes 시스템의 기능을 사용해 만들었기 때문에 Kubernetes를 사용해본 이용자라면 무리없이 적응할 수 있다는 특징이 있습니다.
이번 포스팅에선 Kuberentes환경에서 Prometheus Operator를 사용해 Prometheus 요소들을 구성해보겠습니다.
Prometheus Operator의 자세한 내용은 공식 Github 페이지에서 볼 수 있습니다.
https://github.com/prometheus-operator/prometheus-operator
1. Prometheus Operator환경 준비
Prometheus Operator는 Kuberentes의 기능을 이용하도록 만들어졌기 때문에 꼭 Kubernetes 환경에서 Prometheus를 배포해야 합니다.
그렇기 때문에 우선 Prometheus를 올릴 Kubernetes 환경부터 준비합니다.
본 포스팅에서는 간단한 minikube 클러스터를 준비했습니다.
이후 아래 명령어를 실행해 Prometheus 스택을 배포하기 위한 "monitoring" namespace를 생성합니다.
1
|
kubectl create ns monitoring
|
cs |
다음으로 메트릭을 가져올 예시 어플리케이션을 배포합니다. 아래와 같은 yaml 파일을 생성한 후 kubectl apply 명령어로 default namespace에 애플리케이션을 배포합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-app
namespace: default spec:
replicas: 3
selector:
matchLabels:
app: example-app
template:
metadata:
labels:
app: example-app
spec:
containers:
- name: example-app
image: fabxc/instrumented_app
ports:
- name: web
containerPort: 8080
|
cs |
이후 예시 애플리케이션을 노출할 ClusterIP Service를 생성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
apiVersion: v1
kind: Service
metadata:
labels:
app: example
name: example
namespace: default
uid: b368d0a4-f372-4171-bf35-2ae9a6d15b2e
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: web
port: 8080
protocol: TCP
targetPort: 8080
selector:
app: example
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
|
cs |
이제 Prometheus Operator를 설치할 텐데요. 현재 Prometheus Operator를 설치할 수 있는 방법은 2가지가 존재합니다.
첫 번째는 yaml 파일을 이용한 방법이고, 두 번째는 Helm 패키지 매니저를 이용한 방법입니다. 본 포스팅에서는 첫 번째 yaml 파일을 이용한 방법으로 진행합니다.
helm 패키지 매니저로 설치하고자 하는 분은 아래 링크를 참고해주세요.
Prometheus Operator를 배포하기 위해 아래 명령어로 Prometheus Operator 레포지토리를 가져옵니다.
1
|
git clone https://github.com/prometheus-operator/prometheus-operator.git
|
cs |
가져온 디렉토리의 bundle.yaml 파일에는 Prometheus Operator를 설치하기 위한 CRD(Custom Resource Definition), Clusterrolebinding.. 등의 오브젝트 명세서가 존재합니다. 이 yaml 파일을 적용해 Prometheus Operator를 배포할 수 있습니다.
적용하기 전에 bundle.yaml 파일을 열어 모든 오브젝트의 namespace 값을 미리 생성한 namespace인 "monitoring"으로 변경합니다.
아래와 같이 default가 아닌 다른 namespace에 Prometheus Operator를 사용하고자 하는 경우 namespace들을 변경해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
...
kind: ClusterRoleBinding metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/name: prometheus-operator
app.kubernetes.io/version: 0.55.0
name: prometheus-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus-operator
subjects:
- kind: ServiceAccount
name: prometheus-operator
namespace: monitoring
... |
cs |
변경한 yaml을 아래 명령어로 적용합니다.
1
|
kubectl apply -f ./bundle.yaml --server-side -n monitoring
|
cs |
--server-side 플래그를 붙이지 않으면
The CustomResourceDefinition "prometheuses.monitoring.coreos.com" is invalid: metadata.annotations: Too long
에러가 발생하기 때문에 workaround로 해당 플래그를 붙여 적용합니다.
적용한 후에는 아래와 같이 "monitoring" namespace에 prometheus operator pod가 생성되어 있는 것을 확인할 수 있습니다.
2. Prometheus 서버 생성
이제 Prometheus Operator를 사용할 준비가 끝났습니다.
Prometheus Operator는 위 그림과 같이 관측할 Service들을 ServiceMonitor가 지속적으로 바라보고, Target을 Prometheus 서버로 보내주며, 이 일련의 행위들을 Operator가 관리하는 구조로 이루어져 있습니다.
이 중 Operator는 준비 단계에서 생성된 것을 확인했습니다. 다음에 생성할 오브젝트는 Prometheus 서버입니다.
Prometheus 인스턴스는 Prometheus의 핵심이라고 할 수 있는 서버 인스턴스 Statefulsets이며, Prometheus Operator가 사용하는 오브젝트 중 "prometheuses"로 관리할 수 있습니다.
우선 Prometheus 서버가 사용할 ClusterRole을 생성합니다.
1
2
3
4
5
6
7
8
9
|
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus-k8s
rules:
- nonResourceURLs: - /metrics verbs: - get - apiGroups: - "" resources: - services - pods - endpoints verbs: - get - list - watch |
cs |
다음으로 생성한 ClusterRole의 권한을 부여할 ClusterRoleBinding을 생성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
|
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prometheus-k8s
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prometheus-k8s
subjects:
- kind: ServiceAccount
name: prometheus-k8s
namespace: monitoring
|
cs |
마지막으로 ClusterRoleBinding에서 명시한 ServiceAccount를 생성합니다.
1
2
3
4
5
|
apiVersion: v1
kind : ServiceAccount
metadata:
name: prometheus-k8s
namespace: monitoring
|
cs |
이제 Prometheus Operator를 사용해 Prometheus 서버를 생성할 준비가 되었습니다.
아래 명세를 사용해 Prometheus 서버를 배포합니다.
1
2
3
4
5
6
7
8
9
10
11
|
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s
name: k8s
namespace: monitoring
spec:
baseImage: quay.io/prometheus/prometheus
replicas: 2
serviceAccountName: prometheus-k8s
|
cs |
이후 pod를 확인해보면 statefulset의 관리 아래 prometheus 서버 pod가 2개 떠있는 것을 확인할 수 있습니다. 추가적으로 prometheus-operated라는 ClusterIP 서비스도 생성합니다.
아래 명령여를 사용해 Prometheus 서버의 웹 UI로 진입할 수 있습니다.
1
|
kubectl port-forward svc/prometheus-operated 9090
|
cs |
3. Prometheus ServiceMonitor 생성
지금까지 Prometheus Operator를 사용해 Prometheus 서버 인스턴스를 생성했습니다.
메트릭을 수집하고 저장할 서버가 있다면 메트릭을 수집할 대상도 있어야 하겠죠. Prometheus는 이 대상을 Config 파일에서 Target이라는 이름으로 관리합니다.
하지만 Config 파일을 이용한 관리는 Kuberentes 환경에서 사용하기 불편합니다. Kubernetes 환경에서는 컨테이너 내부의 파일 시스템에서 Write하지 못하기 때문에 Config 파일을 변경할 때마다 configmap을 수정해야 하기 때문입니다.
그래서 Prometheus Operator는 이러한 문제를 해결하기 위해 ServiceMonitor와 PodMonitor라는 개념을 사용합니다.
Servicemonitor는 Prometheus 서버가 메트릭 수집을 위해 Kubernetes의 Service를 바라보도록 하는 Prometheus Operator의 오브젝트입니다.
Podmonitor는 Prometheus 서버가 메트릭 수집을 위해 Kubernetes의 Pod를 바라보도록 하는 Prometheus Operator의 오브젝트입니다.
Prometheus Operator는 Servicemonitor나 Podmonitor 오브젝트가 추가되면 이 두 오브젝트를 참고해서 Prometheus 서버의 Config 파일을 수정합니다. 그럼으로써 Operator는 사용자가 Config 파일을 직접 수정할 필요 없이 자동으로 Target 관리를 수행할 수 있도록 합니다.
이번 포스팅에서는 두 오브젝트 중 Servicemonitor를 사용해 예시 어플리케이션의 메트릭을 수집해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: example
labels:
app: example-app
namespace: default spec:
selector:
matchLabels:
app: example-app
endpoints:
- port: "web"
|
cs |
Servicemonitor와 Podmonitor 매니페스트의 spec.endpoint.port 에 넣을 값은 포트 숫자가 아닌 꼭 "포트 이름"이여야 합니다.
Service에서 포트 이름을 명시하지 않았다면 포트 이름을 명시한 뒤(ex: "web") 오브젝트를 생성해야 합니다.
Servicemonitor를 추가한 뒤 Prometheus UI의 Tartget 페이지로 가면 Prometheus Operator가 추가한 예시 어플리케이션을 볼 수 있어야 하지만, 왠일인지 아무것도 표시되지 않은 것을 볼 수 있습니다.
이는 Prometheus 서버가 다른 namespace에 존재하는 Servicemonitor를 보지 못하기 때문에 일어난 Issue인데요. Prometheus 서버는 "monitoring" namespace에, Servicemonitor와 예시 애플리케이션은 "default" namespace에 존재하기 때문에 이러한 문제가 발생한 것입니다.
문제를 해결하기 위해 Prometheus 오브젝트를 다음과 같이 수정한 후 다시 서버를 다시 배포합니다.
1
2
3
4
5
6
7
8
9
10
11
12
|
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s
name: k8s
namespace: monitoring
spec:
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
replicas: 2
serviceAccountName: prometheus-k8s
|
cs |
ServiceMonitorNamespaceSelector: {} 항목을 추가해야 Servicemonitor가 어떤 namespace에 있어도 존재를 확인할 수 있습니다.
이를 응용해서 특정한 namespace의 Servicemonitor만 식별하고 싶다면 ServiceMonitorNamespaceSelector의 matchLabel을 사용해 지정할 수 있습니다.
Prometheus 오브젝트를 수정 후 Pod를 다시 배포하면 Targer 페이지에서 아래와 같이 Target이 추가된 것을 볼 수 있습니다.
Configuration 페이지로 진입하면 아래와 같이 Config 파일이 수정되어 있는 것을 볼 수 있습니다. Servicemonitor와 Podmonitor는 이렇게 Prometheus Operator가 Config 파일을 수정할 수 있도록 정보를 제공하는 역할을 합니다.
+ Podmonitor vs Servicemonitor 무엇을 사용해야 할까?
앞서 말씀드렸듯이 Pod로 올라온 서비스를 Prometheus의 Target으로 관리하는 방법은 Podmonitor 리소스로 관리하는 것과 Servicemonitor 리소스로 관리하는 2가지 방법이 있습니다.
Podmonitor는 Pod 자체를 모니터링하면서 Scraping하는 것이고 Servicemonitor는 Pod와 연결된 Service를 모니터링하면서 Scrping한다는 차이가 있는데요.
둘 중 어떤 경우에 어떤 리소스를 사용해서 Target을 관리해야 할까요?
마침 이와 같은 의문을 가진 누군가가 오픈한 Issue가 존재했습니다.
https://github.com/prometheus-operator/prometheus-operator/issues/3119
해당 Issue에서 많은 얘기들이 오고갔지만 내용들을 정리하자면 다음과 같습니다.
Podmonitor : Service가 없는 Pod, 혹은 서비스와 관계 없이 특정 Label이 붙은 Pod를 Monitoring하고자 할때 사용한다.
Servicemonitor : Prometheus 환경에서 기본 선택(default choice)으로 사용할 수 있다. 보통 Podmonitor를 사용해야 할 특별한 경우가 아니라면 사용한다.
이름이 의미하는 대로 Podmonitor는 Pod 자체를, Servicemonitor는 Service를 통해 Pod를 Monitoring한다는 차이점이 있기 때문에 Service를 통해서 Pod와 통신하는 것이 권장되는 Kubernetes 환경에서는 특별한 경우가 아니라면 Servicemonitor를 사용해 관리해야 한다는 결론입니다.
이 같은 내용을 참고하여 각 리소스를 사용하시면 될 것 같습니다.
4. Prometheus Alertmanager 생성
Prometheus는 메트릭을 수집하고 분석해주는 기능 외에 메트릭이 특정 값에 도달하면 Alert을 통지하는 기능도 포함하고 있습니다.
여기서 발동된 Alert을 통지해주는 역할을 하는 것이 Alertmanager인데요. 임시적이고 유동적인 Kubernetes 환경의 특성 상 Alertmanager를 관리하는 것이 쉽지 않았습니다.
이같은 관리상의 어려움을 극복하기 위해 Prometheus Operator는 Alertmanager 인스턴스 및 Alert 규칙을 관리해주는 기능을 제공하고 있습니다.
먼저 Prometheus Operator의 "Alertmanager" 오브젝트를 사용해서 Alertmanager 인스턴스를 생성하겠습니다.
1
2
3
4
5
6
7
|
apiVersion: monitoring.coreos.com/v1
kind: Alertmanager
metadata:
name: alertmanager
namespace: monitoring
spec:
replicas: 1
|
cs |
위 매니페스트를 적용한 뒤에는 아래와 같이 alertmanager Pod가 생성된 것을 볼 수 있습니다. 추가적으로 alertmanager-operated라는 clusterIp 서비스도 생성되어 있습니다.
아래 명령어로 Alertmanager의 Web UI로 진입할 수 있습니다.
1
|
kubectl port-forward svc/alertmanager-operated 9093
|
cs |
5. PrometheusRule 생성
Alertmanager 인스턴스를 생성했지만 Alertmanager는 Alert을 통지(notification)할 뿐 실제로 Alert을 발동하는 것은 Prometheus 서버이기 때문에 Alert을 Prometheus에 등록해야 통지를 받을 수 있습니다.
이제 Prometheus Operator를 이용해서 Prometheus에 Alert rule을 등록해보겠습니다.
Alert rule은 "prometheusRule" 오브젝트를 사용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
kind: PrometheusRule
apiVersion: monitoring.coreos.com/v1
metadata:
name: prometheus-alerting-rules
namespace: monitoring
labels:
role: alert-rules
prometheus: k8s
spec:
groups:
- name: alerting_rules
rules:
- alert: process_cpu_seconds_total
expr: process_cpu_seconds_total > 0
for: 10s
labels:
severity: "critical"
namespace: "monitoring" |
cs |
위의 PrometheusRule은 "process_cpu_seconds_total" 메트릭이 0 이상일 시 발동되는 Alert을 명시하고 있습니다.
주의할 점은 spec.groups.rules.labels 항목에 namespace: "monitoring" 값을 넣었다는 것인데, 실제로 이 Alert의 대상은 "default" namespace에 있음에도 불구하고 Alertmanager가 존재하는 namespace인 "monitoring"을 라벨링했습니다.
이는 Alertmanager는 Alertmanager가 존재하는 namespace에서 오는 Alert만 통지하게끔 설계되어 있기 때문인데요. 이는 제작자의 의도이기 때문에 의도적으로 Alertmanager와 같은 namespace를 붙이는 Workaround를 이용해야 합니다. 이에 대한 자세한 내용은 아래 링크에서 볼 수 있습니다.
https://github.com/prometheus-operator/prometheus-operator/issues/3737
이렇게 PrometheusRule을 추가했습니다. 하지만 해당 Rule을 추가한 것만으로는 Prometheus가 이를 감지할 수 없습니다. Prometheus 오브젝트를 아래와 같이 변경합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s
name: k8s
namespace: monitoring
spec:
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
ruleNamespaceSelector: {}
ruleSelector:
matchLabels:
role: alert-rules
replicas: 2
serviceAccountName: prometheus-k8s
|
cs |
명세를 보면 ruleNamespaceSelector: {} 와 ruleSelector.matchLabels.role:alert-rules 항목이 추가된 것을 볼 수 있습니다.
이 항목을 통해 Prometheus는 지정한 Label이 붙은 prometheusRule을 어떤 namespace에 있던지 식별할 수 있습니다. 해당 항목이 없다면 Prometheus는 같은 namespace 내의 prometheusRule만 식별합니다.
다시 Prometheus를 배포한 뒤 Prometheus Web UI로 접근하면 Alerts 페이지에 아래와 같이 Alert이 추가된 것을 볼 수 있습니다.
해당 Alert은 곧바로 조건을 충족하기 때문에 몇 분의 시간이 지나면 아래와 같이 Alert이 발동되는 것 또한 볼 수 있습니다.
6. AlertmanagerConfig 생성
지금까지 Prometheus Operator를 사용해 Alertmanager 인스턴스와 Alertrule까지 생성했습니다.
이제 Alertmanager가 가진 규칙을 토대로 이 Alert을 email, Slack 등 다양한 채널로 통지(notification) 할 수 있습니다.
Prometheus Operator에서 이 규칙을 생성할 수 있는 오브젝트가 AlertmanagerConfig입니다.
AlertmanagerConfig을 적용하기 위해 아래와 같이 yaml 파일을 작성합니다. 본 포스팅에서는 Alert이 발동될 경우 email로 통지가 오도록 해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
name: alertmanager-config
labels:
alertmanagerConfig: alert
spec:
route:
receiver: 'email-notifications'
groupBy: [severity]
receivers:
- name: 'email-notifications'
emailConfigs:
- to: 'my-email@gmail.com'
from: 'my-email@gmail.com'
smarthost: smtp.gmail.com:587
authUsername: 'my-email@gmail.com'
authIdentity: 'my-email@gmail.com'
authPassword:
name: 'authpassword'
key: 'password'
|
cs |
위 매니페스트는 Alert이 발동되었을때 google smtp 서버를 이용해서 my-email@gmail.com 으로 통지를 보내주는 config입니다.
여기서 spec.receivers.emailConfigs.authPassword 항목은 Gmail의 App password 값을 넣어야 합니다. App password를 평문으로 넣으면 보안 Issue가 발생할 수 있으므로 Kubernetes의 Secret을 참조하도록 합니다.
Gmail의 App password는 Google Account -> Security에서 생성할 수 있습니다.
아래 명령어로 App password에 대한 Kuberenetes secret을 생성합니다.
1
|
kubectl create secret generic authpassword --from-literal=password=APP_PASSWORD
|
cs |
그리고 "alertmanager" 오브젝트를 수정해 생성한 AlertmanagerConfig을 사용하도록 설정합니다.
1
2
3
4
5
6
7
8
9
10
|
apiVersion: monitoring.coreos.com/v1
kind: Alertmanager
metadata:
name: alertmanager
namespace: monitoring
spec:
alertmanagerConfigSelector:
matchLabels:
alertmanagerConfig: alert
replicas: 1
|
cs |
spec.alertmanagerConfigSelector.matchLabels 항목에 생성한 AlertmanagerConfig에 붙은 label 값을 넣습니다.
마지막으로 "Prometheus" 오브젝트를 수정해 Alertmanager 와 Prometheus 서버가 통신하도록 설정하겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
labels:
prometheus: k8s
name: k8s
namespace: monitoring
spec:
alerting:
alertmanagers:
- apiVersion: v2
name: alertmanager-operated
namespace: monitoring
port: web
serviceMonitorNamespaceSelector: {}
serviceMonitorSelector: {}
ruleNamespaceSelector: {}
ruleSelector:
matchLabels:
role: alert-rules
replicas: 2
serviceAccountName: prometheus-k8s
|
cs |
위 매니스트에서 spec.alerting.alertmanagers 항목에 alertmanager로 통신할 수 있는 Service 명과 포트 이름을 넣으면 됩니다.
포트는 숫자값이 아닌 이름으로 넣어야 한다는 점 다시 주의 바랍니다.
이렇게 AlertmanagerConfig를 생성했지만 어째선지 Alert이 보이지 않습니다.
prometheus operator의 로그를 확인해보면 Alertmanager config를 생성할때 참조하는 Secret 이름이 잘못된 것을 확인할 수 있습니다.
제 경우에는 Secret 이름이 alertmanager-alertmanager-generated로 되어있었는데요. 이를 alertmanager-alertmanager로 변경해주면 정상적으로 동작합니다.
설정 후 Alertmanager Web UI로 진입하면 아래와 같이 Alert 3개가 Trigger된 것을 볼 수 있습니다.
Status 페이지에서는 Prometheus Operator가 AlertmanagerConfig 오브젝트를 참고해서 작성한 Config를 볼 수 있습니다.
통지를 보낸 email 함을 확인하면 아래와 같이 통지가 온 것을 확인할 수 있습니다.
7. 마무리
지금까지 Prometheus Operator의 Prometheus 서버부터 prometheusRule, Alertmanager 등 다양한 오브젝트를 사용해 Prometheus 구성을 자동화해봤습니다.
기존 Kubernetes 환경은 임시적이고 유동적이라는 특징 때문에 Prometheus를 관리하기 힘들었지만 이렇게 Operator를 이용하면 Config파일을 수정하거나 Service discovery에 신경쓰지 않고도 편하게 Prometheus를 관리할 수 있었습니다.
이번 포스팅에서 다루지 않았지만 prometheus operator에는 Thanosruler, probe 등 이용할 수 있는 다른 오브젝트들도 있기 때문에 관심있다면 아래 공식 Github 페이지에서 확인 바랍니다.
https://github.com/prometheus-operator/prometheus-operator
'Observability' 카테고리의 다른 글
Opentelemetry로 Kubernetes Observability 확보하기 : Monitoring (1) | 2024.03.24 |
---|---|
Opentelemetry로 Kubernetes Observability 확보하기 : Logging (0) | 2024.03.07 |
트레이싱 관측 도구 Grafana Tempo로 트레이스를 관측해보자 (0) | 2022.01.27 |
Elasticsearch에 fluentd를 얹은 EFK stack 구축하기(with kubernetes) (9) | 2022.01.08 |
클라우드 리소스 Observability 확보 도구 Steampipe 사용기 + GCP IAM report 제작기 (0) | 2021.12.27 |