[Kubernetes] Install Alloy(v1.7.1) Using Helm Chart

Helm 설치 및 설명 참고 {: .prompt-info }

Install the Helm charts #

  • namespace 생성

    1kubectl create namespace [NAMESPACE NAME]
  • Alloy 배포

    1helm repo add grafana https://grafana.github.io/helm-charts
    2helm repo update
    3helm install --namespace <NAMESPACE> <RELEASE_NAME> grafana/alloy

    Alloy - Helm 설치 참고

Customize Default Configuration #

kafka 연결 #

 1...✂...
 2
 3alloy:
 4  configMap:
 5    # -- Create a new ConfigMap for the config file.
 6    create: true
 7    # -- Content to assign to the new ConfigMap.  This is passed into `tpl` allowing for templating from values.
 8    content: |
 9      loki.source.kafka "raw" {
10        brokers                = ["kafka:9092"]
11        topics                 = ["loki"]
12        forward_to             = [loki.write.http.receiver]
13        relabel_rules          = loki.relabel.kafka.rules
14        version                = "2.0.0"
15        labels                = {service_name = "raw_kafka"}
16      }
17
18      loki.relabel "kafka" {
19        forward_to      = [loki.write.http.receiver]
20        rule {
21          source_labels = ["__meta_kafka_topic"]
22          target_label  = "topic"
23        }
24      }
25
26      loki.write "http" {
27        endpoint {
28          url = "http://loki:3100/loki/api/v1/push"
29        }
30      }
31
32    # -- Name of existing ConfigMap to use. Used when create is false.
33    name: null
34    # -- Key in ConfigMap to get config from.
35    key: null
36
37...✂...

참고 - https://grafana.com/docs/loki/latest/send-data/alloy/examples/alloy-kafka-logs/ {: .prompt-info }

Kafka를 통해 OpenTelemetry logs 수집 #

 1...✂...
 2
 3alloy:
 4  configMap:
 5    # -- Create a new ConfigMap for the config file.
 6    create: true
 7    # -- Content to assign to the new ConfigMap.  This is passed into `tpl` allowing for templating from values.
 8    content: |
 9      loki.source.kafka "raw" {
10        brokers                = ["kafka:9092"]
11        topics                 = ["loki"]
12        forward_to             = [loki.write.http.receiver]
13        relabel_rules          = loki.relabel.kafka.rules
14        version                = "2.0.0"
15        labels                = {service_name = "raw_kafka"}
16      }
17
18      loki.relabel "kafka" {
19        forward_to      = [loki.write.http.receiver]
20        rule {
21          source_labels = ["__meta_kafka_topic"]
22          target_label  = "topic"
23        }
24      }
25
26      loki.write "http" {
27        endpoint {
28          url = "http://loki:3100/loki/api/v1/push"
29        }
30      }
31
32
33      otelcol.receiver.kafka "default" {
34        brokers          = ["kafka:9092"]
35        protocol_version = "2.0.0"
36        topic           = "otlp"
37        encoding        = "otlp_proto"
38
39        output {
40          logs    = [otelcol.processor.batch.default.input]
41        }
42      }
43
44      otelcol.processor.batch "default" {
45          output {
46              logs = [otelcol.exporter.otlphttp.default.input]
47          }
48      }
49
50      otelcol.exporter.otlphttp "default" {
51        client {
52          endpoint = "http://loki:3100/otlp"
53        }
54      }
55
56    # -- Name of existing ConfigMap to use. Used when create is false.
57    name: null
58    # -- Key in ConfigMap to get config from.
59    key: null
60
61...✂...

참고 - https://grafana.com/docs/loki/latest/send-data/alloy/examples/alloy-kafka-logs/ {: .prompt-info }

Kubernetes Pods logs 연결 #

  1...✂...
  2
  3alloy:
  4  configMap:
  5    # -- Create a new ConfigMap for the config file.
  6    create: true
  7    # -- Content to assign to the new ConfigMap.  This is passed into `tpl` allowing for templating from values.
  8    content: |
  9      loki.write "http" {
 10        endpoint {
 11          url = "http://loki:3100/loki/api/v1/push"
 12        }
 13      }
 14
 15      // discovery.kubernetes allows you to find scrape targets from Kubernetes resources.
 16      // It watches cluster state and ensures targets are continually synced with what is currently running in your cluster.
 17      discovery.kubernetes "pod" {
 18        role = "pod"
 19      }
 20
 21      // discovery.relabel rewrites the label set of the input targets by applying one or more relabeling rules.
 22      // If no rules are defined, then the input targets are exported as-is.
 23      discovery.relabel "pod_logs" {
 24        targets = discovery.kubernetes.pod.targets
 25
 26        // Label creation - "namespace" field from "__meta_kubernetes_namespace"
 27        rule {
 28          source_labels = ["__meta_kubernetes_namespace"]
 29          action = "replace"
 30          target_label = "namespace"
 31        }
 32
 33        // Label creation - "pod" field from "__meta_kubernetes_pod_name"
 34        rule {
 35          source_labels = ["__meta_kubernetes_pod_name"]
 36          action = "replace"
 37          target_label = "pod"
 38        }
 39
 40        // Label creation - "container" field from "__meta_kubernetes_pod_container_name"
 41        rule {
 42          source_labels = ["__meta_kubernetes_pod_container_name"]
 43          action = "replace"
 44          target_label = "container"
 45        }
 46
 47        // Label creation -  "app" field from "__meta_kubernetes_pod_label_app_kubernetes_io_name"
 48        rule {
 49          source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"]
 50          action = "replace"
 51          target_label = "app"
 52        }
 53
 54        // Label creation -  "job" field from "__meta_kubernetes_namespace" and "__meta_kubernetes_pod_container_name"
 55        // Concatenate values __meta_kubernetes_namespace/__meta_kubernetes_pod_container_name
 56        rule {
 57          source_labels = ["__meta_kubernetes_namespace", "__meta_kubernetes_pod_container_name"]
 58          action = "replace"
 59          target_label = "job"
 60          separator = "/"
 61          replacement = "$1"
 62        }
 63
 64        // Label creation - "container" field from "__meta_kubernetes_pod_uid" and "__meta_kubernetes_pod_container_name"
 65        // Concatenate values __meta_kubernetes_pod_uid/__meta_kubernetes_pod_container_name.log
 66        rule {
 67          source_labels = ["__meta_kubernetes_pod_uid", "__meta_kubernetes_pod_container_name"]
 68          action = "replace"
 69          target_label = "__path__"
 70          separator = "/"
 71          replacement = "/var/log/pods/*$1/*.log"
 72        }
 73
 74        // Label creation -  "container_runtime" field from "__meta_kubernetes_pod_container_id"
 75        rule {
 76          source_labels = ["__meta_kubernetes_pod_container_id"]
 77          action = "replace"
 78          target_label = "container_runtime"
 79          regex = "^(\\S+):\\/\\/.+$"
 80          replacement = "$1"
 81        }
 82      }
 83
 84      // loki.source.kubernetes tails logs from Kubernetes containers using the Kubernetes API.
 85      loki.source.kubernetes "pod_logs" {
 86        targets    = discovery.relabel.pod_logs.output
 87        forward_to = [loki.process.pod_logs.receiver]
 88      }
 89
 90      // loki.process receives log entries from other Loki components, applies one or more processing stages,
 91      // and forwards the results to the list of receivers in the component's arguments.
 92      loki.process "pod_logs" {
 93        stage.static_labels {
 94            values = {
 95              cluster = "<CLUSTER_NAME>",
 96            }
 97        }
 98
 99        forward_to = [loki.write.<WRITE_COMPONENT_NAME>.receiver]
100      }
101
102    # -- Name of existing ConfigMap to use. Used when create is false.
103    name: null
104    # -- Key in ConfigMap to get config from.
105    key: null
106
107...✂...

참고 - https://grafana.com/docs/alloy/latest/collect/logs-in-kubernetes/#pods-logs {: .prompt-info }

외부 접속을 위한 NodePort 설정 #

 1...✂...
 2
 3service:
 4  # -- Creates a Service for the controller's pods.
 5  enabled: true
 6  # -- Service type
 7  type: NodePort
 8  # -- NodePort port. Only takes effect when `service.type: NodePort`
 9  nodePort: 31128
10  # -- Cluster IP, can be set to None, empty "" or an IP address
11  clusterIP: ''
12  # -- Value for internal traffic policy. 'Cluster' or 'Local'
13  internalTrafficPolicy: Cluster
14  annotations: {}
15    # cloud.google.com/load-balancer-type: Internal
16
17...✂...

외부 접속을 위한 Ingress 설정 #

 1...✂...
 2
 3ingress:
 4  # -- Enables ingress for Alloy (Faro port)
 5  enabled: true
 6  # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName
 7  # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress
 8  # ingressClassName: nginx
 9  # Values can be templated
10  annotations:
11    {}
12    # kubernetes.io/ingress.class: nginx
13    # kubernetes.io/tls-acme: "true"
14  labels: {}
15  path: /
16  faroPort: 12345
17
18  # pathType is only for k8s >= 1.1=
19  pathType: Prefix
20
21  hosts:
22    - chart-example.local
23  ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services.
24  extraPaths: []
25  # - path: /*
26  #   backend:
27  #     serviceName: ssl-redirect
28  #     servicePort: use-annotation
29  ## Or for k8s > 1.19
30  # - path: /*
31  #   pathType: Prefix
32  #   backend:
33  #     service:
34  #       name: ssl-redirect
35  #       port:
36  #         name: use-annotation
37
38  tls: []
39  #  - secretName: chart-example-tls
40  #    hosts:
41  #      - chart-example.local
42
43...✂...

Install Customize Default Configuration #

1helm install -n <NAMESPACE> [RELEASE NAME] [Chart.yaml 경로] -f [YAML 파일 또는 URL에 값 지정 (여러 개를 지정가능)]
1helm install --namespace <NAMESPACE> [RELEASE NAME] grafana/alloy -f override-values.yaml

Uninstall the Chart #

1helm uninstall [RELEASE NAME] -n [NAMESPACE NAME]
Advertisement