Thanos
Prometheus 의 한계점
scale-out 기능의 부재
single 서버로 구현되어 scale-out 을 할 수 없다.
고가용성
역시 single 서버로 구현되어 Prometheus 다운 또는 버전업을 위한 shutdown 시 모니터링이 중지된다.
Thanos 의 장점
Global Query View
다수의 Prometheus 서버에서 수집된 로그에 대해 한번에 조회할 수 있다.
Unlimited Retention
저장된 로그를 S3 와 같은 외부 저장공간에 저장할 수 있다.
따라서, 로컬 스토리지의 한계로 인한 저장 기간의 제한이 없다.
Prometheus Compatible
Prometheus 의 한계점을 커버해준다.
Downsampling & Compaction
장기간의 로그를 조회할 경우, 실제 데이타는 10초 간격이라 해도,
조회에 필요한 데이타는 10분에 한건으로 다운샘플링할 수 있다.
Thanos architecture
Thanos Sidecar
Prometheus 의 작동을 방해하지 않고, 옆에서 같이 데이타를 수집합니다.
Thanos Store
로그 데이타를 저장합니다.
S3 와 같은 외부 저장공간으로 로그를 전송 또는 다시 가져올 수 있다.
Thanos Querier
다수의 Prometheus 서버에서 수집된 로그를 한번에 조회할 수 있다.
Thanos Compactor
로그데이타를 다운샘플링할 수 있다.
Deploying on HashiCorp Nomad
Nomad Cluster 구성
https://github.com/skyer9/NomadClusterForDev 를 참조해서 Test Nomad Cluster 를 구성합니다.
https://github.com/skyer9/TerraformOnAws/blob/main/run_jobs/haproxy.nomad 를 참조해서 reverse proxy 를 추가합니다.
설정 변경
아래 명령으로 prometheus 를 위한 로그를 생성합니다.
sudo vi /etc/nomad.d/nomad.hcl
---------------------------------------
......
client {
host_volume "prometheus" {
# add directory manually
# sudo mkdir -p /opt/nomad-volumes/prometheus
# sudo chown 65534:65534 /opt/nomad-volumes/prometheus
path = "/opt/nomad-volumes/prometheus"
read_only = false
}
}
......
telemetry {
collection_interval = "5s"
disable_hostname = true
publish_allocation_metrics = true
publish_node_metrics = true
prometheus_metrics = true
}
---------------------------------------
cni-plugins 설치
curl -L -o cni-plugins.tgz https://github.com/containernetworking/plugins/releases/download/v0.8.1/cni-plugins-linux-amd64-v0.8.1.tgz
sudo mkdir -p /opt/cni/bin
sudo tar -C /opt/cni/bin -xzf cni-plugins.tgz
prometheus 설치
https://github.com/skyer9/TerraformOnAws/blob/main/run_jobs/prometheus.nomad 를 참조해서 prometheus 를 설치합니다.
볼륨을 추가해 줍니다.
args = [
"--config.file=/etc/prometheus/config/prometheus.yml",
"--storage.tsdb.path=/prometheus",
"--web.listen-address=0.0.0.0:${NOMAD_PORT_prometheus_ui}",
"--web.console.libraries=/usr/share/prometheus/console_libraries",
"--web.console.templates=/usr/share/prometheus/consoles",
# for Thanos
# "--storage.tsdb.max-block-duration=2h",
# "--storage.tsdb.min-block-duration=2h",
]
job "prometheus" {
group "prometheus" {
volume "prometheus" {
type = "host"
source = "prometheus"
}
task "prometheus" {
volume_mount {
volume = "prometheus"
destination = "/prometheus"
}
}
}
}
Thanos 설치
vi thanos-sidecar.nomad
---------------------------------------
job "thanos-sidecar" {
datacenters = ["dc1"]
group "thanos-sidecar" {
count = 1
network {
mode = "bridge"
port "grpc" {
to = 10901
}
port "http" {
to = 10902
}
}
service {
name = "thanos-sidecar"
port = "grpc"
tags = ["grpc"]
}
service {
name = "thanos-sidecar"
port = "http"
tags = ["http"]
}
volume "prometheus" {
type = "host"
read_only = false
source = "prometheus"
}
task "thanos-sidecar" {
driver = "docker"
volume_mount {
volume = "prometheus"
destination = "/prometheus"
read_only = false
}
template {
change_mode = "noop"
destination = "local/bucket.yml"
data = <<EOH
type: S3
config:
bucket: <your-bucket-name>
endpoint: <your-bucket-endpoint>
signature_version2: true
access_key: <your-bucket-access-key>
secret_key: <your-bucket-secret-key>
EOH
}
config {
image = "quay.io/thanos/thanos:v0.22.0"
auth_soft_fail = true
# host 로 설정했으므로 127.0.0.1 는 호스트를 가르킨다.
network_mode = "host"
args = [
"sidecar",
"--tsdb.path=/prometheus",
"--prometheus.url=http://localhost:9090/",
"--grpc-address=0.0.0.0:10901",
"--http-address=0.0.0.0:10902",
"--objstore.config-file=/etc/thanos/bucket.yml"
]
volumes = [
"local/bucket.yml:/etc/thanos/bucket.yml",
]
}
resources {
memory = 1024
}
}
}
}
---------------------------------------
vi thanos-store.nomad
---------------------------------------
job "thanos-store" {
datacenters = ["dc1"]
group "thanos-store" {
count = 1
network {
mode = "bridge"
port "grpc" {
to = 10901
}
port "http" {
to = 10902
}
}
service {
name = "thanos-store"
port = "grpc"
tags = ["grpc"]
}
service {
name = "thanos-store"
port = "http"
tags = ["http"]
}
task "thanos-store" {
driver = "docker"
template {
change_mode = "noop"
destination = "local/bucket.yml"
data = <<EOH
type: S3
config:
bucket: <your-bucket-name>
endpoint: <your-bucket-endpoint>
signature_version2: true
access_key: <your-bucket-access-key>
secret_key: <your-bucket-secret-key>
EOH
}
config {
image = "quay.io/thanos/thanos:v0.22.0"
# host 로 설정했으므로 127.0.0.1 는 호스트를 가르킨다.
network_mode = "host"
auth_soft_fail = true
args = [
"store",
"--grpc-address=0.0.0.0:10901",
"--http-address=0.0.0.0:10902",
"--objstore.config-file=/etc/thanos/bucket.yml"
]
volumes = [
"local/bucket.yml:/etc/thanos/bucket.yml",
]
}
}
}
}
---------------------------------------
vi thanos-query.nomad
---------------------------------------
job "thanos-query" {
datacenters = ["dc1"]
group "thanos-query" {
count = 1
network {
mode = "bridge"
port "http" {
to = 10902
}
}
service {
name = "thanos-query"
port = "http"
check {
name = "thanos query port alive"
type = "http"
path = "/-/healthy"
interval = "10s"
timeout = "2s"
}
}
task "thanos-query" {
driver = "docker"
template {
change_mode = "restart"
destination = "local/targets.yml"
data = <<EOH
- targets:{{ range service "thanos-sidecar" }}{{if .Tags | contains "grpc"}}
- '{{ .Address }}:{{ .Port }}'{{ end }}{{ end }}
- targets:{{ range service "thanos-store" }}{{if .Tags | contains "grpc"}}
- '{{ .Address }}:{{ .Port }}'{{ end }}{{ end }}
EOH
}
config {
image = "quay.io/thanos/thanos:v0.22.0"
# host 로 설정했으므로 127.0.0.1 는 호스트를 가르킨다.
network_mode = "host"
auth_soft_fail = true
args = [
"query",
"--grpc-address=0.0.0.0:10901",
"--http-address=0.0.0.0:10902",
"--query.replica-label=prometheus_replica",
"--query.replica-label=rule_replica",
"--store.sd-files=/etc/targets.yml",
"--web.external-prefix=/thanos/",
"--web.route-prefix=/thanos/"
]
volumes = [
"local/targets.yml:/etc/targets.yml",
]
}
}
}
}
---------------------------------------
vi thanos-compactor.nomad
---------------------------------------
job "thanos-compactor" {
datacenters = ["dc1"]
group "thanos-compactor" {
count = 1
network {
mode = "bridge"
port "grpc" {
to = 10901
}
port "http" {
to = 10902
}
}
service {
name = "thanos-compactor"
port = "grpc"
tags = ["grpc"]
}
service {
name = "thanos-compactor"
port = "http"
tags = ["http"]
}
task "thanos-compactor" {
driver = "docker"
template {
change_mode = "noop"
destination = "local/bucket.yml"
data = <<EOH
type: S3
config:
bucket: <your-bucket-name>
endpoint: <your-bucket-endpoint>
signature_version2: true
access_key: <your-bucket-access-key>
secret_key: <your-bucket-secret-key>
EOH
}
config {
image = "quay.io/thanos/thanos:v0.22.0"
# host 로 설정했으므로 127.0.0.1 는 호스트를 가르킨다.
network_mode = "host"
auth_soft_fail = true
args = [
"compact",
"--wait",
"--objstore.config-file=/etc/thanos/bucket.yml"
]
volumes = [
"local/bucket.yml:/etc/thanos/bucket.yml",
]
}
}
}
}
---------------------------------------
port "thanos_http" {
static = 10902
}
frontend thanos_http_front
bind *:{{ env "NOMAD_PORT_thanos_http" }}
default_backend thanos_http_back
backend thanos_http_back
balance roundrobin
server-template thanos_http 5 _thanos-query._tcp.service.consul resolvers consul resolve-opts allow-dup-ip resolve-prefer ipv4 check