AWS에서 Loki Helm 차트 배포
이 가이드에서는 Helm 차트를 사용하여 AWS에 최소 실행 가능한 Loki를 마이크로서비스 모드로 배포하는 방법을 보여줍니다. 이 가이드를 진행하려면 다음과 같이 AWS에 리소스를 배포하는 데 필요한 도구와 권한이 있어야 합니다.
- EKS(Amazon Elastic Kubernetes Service)에 대한 전체 액세스
- S3(Amazon Simple Storage Service)에 대한 전체 액세스
- IAM(Identity Access Management) 역할 및 정책을 생성할 수 있는 충분한 권한
Loki를 AWS S3에 인증하고 연결하는 방법에는 두 가지가 있습니다. IAM 역할을 통해 액세스 권한을 부여하는 권장 방법을 안내해 드립니다.
고려 사항
주의: 이 가이드는 2024년 10월 31일에 마지막으로 업데이트되었을 때 정확했습니다. 클라우드 제공업체는 서비스와 제품을 자주 업데이트하므로, 버킷을 만들고 역할을 할당하기 전에 AWS S3 설명서 (opens in a new tab)를 참조하는 것이 가장 좋습니다.
- IAM 역할: 이 가이드에서 생성된 IAM 역할은 Loki가 S3 버킷에 읽고 쓸 수 있도록 허용하는 기본 역할입니다. 요구 사항에 따라 더 세분화된 권한을 추가할 수 있습니다.
- 인증: Grafana Loki는 기본 인증 계층과 함께 제공됩니다. 이 예에서는 Loki 게이트웨이(NGINX)가 기본 인증을 사용하여 인터넷에 노출됩니다. NGINX는 다른 오픈 소스 리버스 프록시로 대체할 수도 있습니다. 자세한 내용은 인증을 참조하십시오.
- 보존:
values.yaml
파일에서 보존 기간은 28일로 설정되어 있습니다. 요구 사항에 따라 이 값을 조정할 수 있습니다. - 비용: AWS에서 Loki를 실행하면 비용이 발생합니다. 예기치 않은 청구서를 피하려면 사용량과 비용을 모니터링해야 합니다. 이 가이드에서는 3개의 노드와 m5.xlarge 인스턴스가 있는 간단한 EKS 클러스터를 사용했습니다. 워크로드에 따라 인스턴스 유형과 노드 수를 조정할 수 있습니다.
전제 조건
- Helm 3 이상. Helm 설치 (opens in a new tab)를 참조하십시오. 로컬 컴퓨터에 설치해야 합니다.
- AWS에서 실행 중인 쿠버네티스 클러스터. 시작하는 간단한 방법은 EKSctl을 사용하는 것입니다. EKSctl 시작하기 (opens in a new tab)를 참조하십시오.
- 로컬 컴퓨터에 Kubectl이 설치되어 있어야 합니다. kubectl 설치 및 설정 (opens in a new tab)을 참조하십시오.
- (선택 사항) 로컬 컴퓨터에 AWS CLI가 설치되어 있어야 합니다. AWS CLI 설치 (opens in a new tab)를 참조하십시오. EKSctl을 사용하여 EKS 클러스터를 만들고 IAM 역할 및 정책을 로컬에서 수정하려는 경우 필요합니다.
EKS 최소 요구 사항
주의: 이러한 EKS 요구 사항은 이 가이드를 사용하여 Loki를 배포하는 데 필요한 최소 사양입니다. AWS 환경 및 워크로드에 따라 플러그인 및 인스턴스 유형을 조정할 수 있습니다. 그렇게 할 경우 이 샘플 구성이 여전히 요구 사항을 충족하는지 보장할 수 없습니다.
이 가이드에서는 m5.xlarge
인스턴스를 사용하여 Loki를 배포합니다. 이는 대부분의 시나리오에서 작동해야 하는 인스턴스 유형입니다. 그러나 특정 요구 사항에 따라 인스턴스 유형과 수를 수정할 수 있습니다.
EKS에 Loki를 배포하기 위한 최소 요구 사항은 다음과 같습니다.
- 쿠버네티스 버전
1.30
이상. - EKS 클러스터용 노드
3
개. - 인스턴스 유형은 워크로드에 따라 다릅니다. 프로덕션 클러스터의 좋은 시작점은
m7i.2xlarge
입니다.
이 가이드에서 사용된 EKSctl 클러스터 구성 파일은 다음과 같습니다.
# ClusterConfig 객체의 간단한 예:
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: <INSERT-CLUSTER-NAME>
region: <INSERT-REGION-FOR-CLUSTER>
version: "1.31"
iam:
withOIDC: true
addons:
- name: aws-ebs-csi-driver
managedNodeGroups:
- name: loki-workers
instanceType: m7i.2xlarge
desiredCapacity: 3
minSize: 2
maxSize: 3
amiFamily: AmazonLinux2023
iam:
withAddonPolicies:
ebs: true
volumeSize: 80
volumeType: gp3
ebsOptimized: true
EKS 클러스터 내에 다음 플러그인도 설치해야 합니다.
- Amazon EBS CSI 드라이버: 쿠버네티스가 애플리케이션의 영구 저장소로 EBS 볼륨을 동적으로 프로비저닝하고 관리할 수 있도록 합니다. 이를 사용하여 Loki의 노드 볼륨을 프로비저닝합니다.
- CoreDNS: 쿠버네티스 클러스터에 대한 내부 DNS 서비스를 제공하여 서비스와 파드가 DNS 이름을 사용하여 서로 통신할 수 있도록 합니다.
- kube-proxy: 노드의 네트워크 규칙을 유지 관리하여 클러스터 내 파드와 서비스 간의 통신을 활성화합니다.
또한 EKS 클러스터에 OIDC(OpenID Connect) 공급자를 설치해야 합니다. 이는 IAM 역할과 정책이 올바르게 작동하는 데 필요합니다. EKSctl을 사용하는 경우 다음 명령을 사용하여 OIDC 공급자를 설치할 수 있습니다.
팁: 위 EKSctl 구성 파일을 사용하여 클러스터를 만든 경우 이 명령을 실행할 필요가 없습니다. OIDC 공급자는 자동으로 설치됩니다.
eksctl utils associate-iam-oidc-provider --cluster loki --approve
S3 버킷 생성
경고: 기본 버킷 이름인 chunk
, ruler
및 admin
을 사용하지 마십시오. 각 버킷에 대해 고유한 이름을 선택하십시오. 자세한 내용은 다음 보안 업데이트를 참조하십시오.
Loki를 배포하기 전에 두 개의 S3 버킷을 만들어야 합니다. 하나는 로그(청크)를 저장하고 다른 하나는 경고 규칙을 저장합니다. AWS 관리 콘솔 또는 AWS CLI를 사용하여 버킷을 만들 수 있습니다. 버킷 이름은 전역적으로 고유해야 합니다.
참고: GEL 고객은 관리자 데이터를 저장하기 위해 세 번째 버킷이 필요합니다. 이 버킷은 OSS 사용자에게는 필요하지 않습니다.
aws s3api create-bucket --bucket <YOUR CHUNK BUCKET NAME e.g. `loki-aws-dev-chunks`> --region <S3 region your account is on, e.g. `eu-west-2`> --create-bucket-configuration LocationConstraint=<S3 region your account is on, e.g. `eu-west-2`> \
aws s3api create-bucket --bucket <YOUR RULER BUCKET NAME e.g. `loki-aws-dev-ruler`> --region <S3 REGION your account is on, e.g. `eu-west-2`> --create-bucket-configuration LocationConstraint=<S3 REGION your account is on, e.g. `eu-west-2`>
region
및 bucket
이름을 원하는 값으로 바꾸십시오. 이 가이드의 뒷부분에서 버킷 정책을 다시 살펴보겠습니다.
IAM 역할 및 정책 정의
Loki를 AWS S3에 연결하는 권장 방법은 IAM 역할을 사용하는 것입니다. 이 방법은 Loki 구성에 직접 저장되는 액세스 키 및 비밀 키를 사용하는 것보다 더 안전합니다. 역할 및 정책은 AWS CLI 또는 AWS 관리 콘솔을 사용하여 만들 수 있습니다. 아래 단계는 AWS CLI를 사용하여 역할 및 정책을 만드는 방법을 보여줍니다.
-
새 디렉토리를 만들고 해당 디렉토리로 이동합니다. 이 디렉토리에 파일을 만들어야 합니다. 이 가이드의 모든 명령은 이 디렉토리에 있다고 가정합니다.
-
다음 내용으로
loki-s3-policy.json
파일을 만듭니다.{ "Version": "2012-10-17", "Statement": [ { "Sid": "LokiStorage", "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": [ "arn:aws:s3:::< CHUNK BUCKET NAME >", "arn:aws:s3:::< CHUNK BUCKET NAME >/*", "arn:aws:s3:::< RULER BUCKET NAME >", "arn:aws:s3:::< RULER BUCKET NAME >/*" ] } ] }
자리 표시자를 이전에 만든 버킷의 이름으로 바꾸십시오.
-
AWS CLI를 사용하여 IAM 정책을 만듭니다.
aws iam create-policy --policy-name LokiS3AccessPolicy --policy-document file://loki-s3-policy.json
-
다음 내용으로
trust-policy.json
이라는 신뢰 정책 문서를 만듭니다.{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::< ACCOUNT ID >:oidc-provider/oidc.eks.<INSERT REGION>.amazonaws.com/id/< OIDC ID >" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "oidc.eks.<INSERT REGION>.amazonaws.com/id/< OIDC ID >:sub": "system:serviceaccount:loki:loki", "oidc.eks.<INSERT REGION>.amazonaws.com/id/< OIDC ID >:aud": "sts.amazonaws.com" } } } ] }
자리 표시자를 AWS 계정 ID, 지역 및 OIDC ID(EKS 클러스터 구성에서 찾을 수 있음)로 바꾸십시오.
-
AWS CLI를 사용하여 IAM 역할을 만듭니다.
aws iam create-role --role-name LokiServiceAccountRole --assume-role-policy-document file://trust-policy.json
-
정책을 역할에 연결합니다.
aws iam attach-role-policy --role-name LokiServiceAccountRole --policy-arn arn:aws:iam::<Account ID>:policy/LokiS3AccessPolicy
자리 표시자를 AWS 계정 ID로 바꾸십시오.
Helm 차트 배포
Loki Helm 차트를 배포하기 전에 Helm에 Grafana 차트 리포지토리를 추가해야 합니다. 이 리포지토리에는 Loki Helm 차트가 포함되어 있습니다.
-
Helm에 Grafana 차트 리포지토리를 추가합니다.
helm repo add grafana https://grafana.github.io/helm-charts
-
차트 리포지토리를 업데이트합니다.
helm repo update
-
Loki를 위한 새 네임스페이스를 만듭니다.
kubectl create namespace loki
Loki 기본 인증
Loki는 기본적으로 인증 기능이 없습니다. Loki를 AWS에 배포하고 게이트웨이를 인터넷에 노출할 것이므로 최소한 기본 인증을 추가하는 것이 좋습니다. 이 가이드에서는 Loki에 사용자 이름과 암호를 부여합니다.
-
시작하려면 사용자 이름과 암호가 있는
.htpasswd
파일을 만들어야 합니다.htpasswd
명령을 사용하여 파일을 만들 수 있습니다.팁:
htpasswd
명령이 설치되어 있지 않은 경우 OS에 따라brew
,apt-get
또는yum
을 사용하여 설치할 수 있습니다.htpasswd -c .htpasswd <username>
이렇게 하면
loki
라는 사용자 이름으로auth
라는 파일이 생성됩니다. 암호를 입력하라는 메시지가 표시됩니다. -
.htpasswd
파일로 쿠버네티스 시크릿을 만듭니다.kubectl create secret generic loki-basic-auth --from-file=.htpasswd -n loki
이렇게 하면
loki
네임스페이스에loki-basic-auth
라는 시크릿이 생성됩니다. Loki Helm 차트 구성에서 이 시크릿을 참조합니다. -
카나리를 위한
canary-basic-auth
시크릿을 만듭니다.kubectl create secret generic canary-basic-auth \ --from-literal=username=<USERNAME> \ --from-literal=password=<PASSWORD> \ -n loki
Loki 카나리가 Loki 게이트웨이로 인증하기 위해 사용자 이름과 암호가 있는 리터럴 시크릿을 만듭니다. 자리 표시자를 원하는 사용자 이름과 암호로 바꾸십시오.
Loki Helm 차트 구성
요구 사항에 가장 적합한 구성 옵션을 선택하여 values.yaml
파일을 만듭니다. 아래는 마이크로서비스 모드에서 Loki Helm 차트에 대한 values.yaml
파일의 예입니다.
loki:
schemaConfig:
configs:
- from: "2024-04-01"
store: tsdb
object_store: s3
schema: v13
index:
prefix: loki_index_
period: 24h
storage_config:
aws:
region: <S3 BUCKET REGION>
# for example, eu-west-2
bucketnames: <CHUNK BUCKET NAME>
# Your actual S3 bucket name, for example, loki-aws-dev-chunks
s3forcepathstyle: false
ingester:
chunk_encoding: snappy
pattern_ingester:
enabled: true
limits_config:
allow_structured_metadata: true
volume_enabled: true
retention_period: 672h
# 28 days retention
compactor:
retention_enabled: true
delete_request_store: s3
ruler:
enable_api: true
storage:
type: s3
s3:
region: <S3 BUCKET REGION>
# for example, eu-west-2
bucketnames: <RULER BUCKET NAME>
# Your actual S3 bucket name, for example, loki-aws-dev-ruler
s3forcepathstyle: false
alertmanager_url: http://prom:9093
# The URL of the Alertmanager to send alerts (Prometheus, Mimir, etc.)
querier:
max_concurrent: 4
storage:
type: s3
bucketNames:
chunks: "<CHUNK BUCKET NAME>"
# Your actual S3 bucket name (loki-aws-dev-chunks)
ruler: "<RULER BUCKET NAME>"
# Your actual S3 bucket name (loki-aws-dev-ruler)
# admin: "<Insert s3 bucket name>" # Your actual S3 bucket name (loki-aws-dev-admin) - GEL customers only
s3:
region: <S3 BUCKET REGION>
# eu-west-2
#insecure: false
# s3forcepathstyle: false
serviceAccount:
create: true
annotations:
"eks.amazonaws.com/role-arn": "arn:aws:iam::<Account ID>:role/LokiServiceAccountRole"
# The service role you created
deploymentMode: Distributed
ingester:
replicas: 3
zoneAwareReplication:
enabled: false
querier:
replicas: 3
maxUnavailable: 2
queryFrontend:
replicas: 2
maxUnavailable: 1
queryScheduler:
replicas: 2
distributor:
replicas: 3
maxUnavailable: 2
compactor:
replicas: 1
indexGateway:
replicas: 2
maxUnavailable: 1
ruler:
replicas: 1
maxUnavailable: 1
# This exposes the Loki gateway so it can be written to and queried externaly
gateway:
service:
type: LoadBalancer
basicAuth:
enabled: true
existingSecret: loki-basic-auth
# Since we are using basic auth, we need to pass the username and password to the canary
lokiCanary:
extraArgs:
- --pass=$(LOKI_PASS)
- --user=$(LOKI_USER)
extraEnv:
- name: LOKI_PASS
valueFrom:
secretKeyRef:
name: canary-basic-auth
key: password
- name: LOKI_USER
valueFrom:
secretKeyRef:
name: canary-basic-auth
key: username
# Enable minio for storage
minio:
enabled: false
backend:
replicas: 0
read:
replicas: 0
write:
replicas: 0
singleBinary:
replicas: 0
주의: 자리 표시자를 실제 값으로 바꾸십시오.
Loki 배포에 유효한 values.yaml
파일을 정의하는 것이 중요합니다. 잘못된 구성의 위험을 제거하기 위해 AWS에 배포할 때 염두에 두어야 할 구성 옵션을 분석해 보겠습니다.
- Loki 구성 대 Values 구성:
values.yaml
파일에는 Loki 구성 파일의 직접적인 표현인loki
라는 섹션이 포함되어 있습니다.- 이 섹션은 스키마, 스토리지 및 쿼리어 구성을 포함한 Loki 구성을 정의합니다.
- 청크에 대해 집중해야 할 주요 구성은
storage_config
섹션이며, 여기서 S3 버킷 지역과 이름을 정의합니다. 이는 Loki에 청크를 저장할 위치를 알려줍니다. ruler
섹션은 S3 버킷 지역 및 이름을 포함한 눈금자 구성을 정의합니다. 이는 Loki에 경고 및 기록 규칙을 저장할 위치를 알려줍니다.- 전체 Loki 구성은 Loki 구성 설명서를 참조하십시오.
- 스토리지:
- Helm 차트가 데이터를 저장하는 위치를 정의합니다.
- Amazon S3를 사용하므로 유형을
s3
으로 설정합니다. - 청크 및 눈금자의 버킷 이름을 이전에 만든 버킷과 일치하도록 구성합니다.
s3
섹션은 버킷의 지역을 지정합니다.
- 서비스 계정:
serviceAccount
섹션은 Loki 서비스 계정에 대한 IAM 역할을 정의하는 데 사용됩니다.- 이전에 만든 IAM 역할이 연결되는 곳입니다.
- 게이트웨이:
- Loki 게이트웨이가 노출되는 방법을 정의합니다.
- 이 구성에서는
LoadBalancer
서비스 유형을 사용하고 있습니다.
Loki 배포
이제 values.yaml
파일을 만들었으므로 Helm 차트를 사용하여 Loki를 배포할 수 있습니다.
-
새로 만든
values.yaml
파일을 사용하여 배포합니다.helm install --values values.yaml loki grafana/loki -n loki --create-namespace
신뢰 정책이
loki
네임스페이스의loki
서비스 계정에서 IAM 역할을 사용하도록 허용하도록 설정되어 있으므로loki
라는 네임스페이스를 만드는 것이 중요합니다. 이는 구성 가능하지만 서비스 계정을 업데이트해야 합니다. -
배포를 확인합니다.
kubectl get pods -n loki
Loki 파드가 실행 중인 것을 볼 수 있습니다.
NAME READY STATUS RESTARTS AGE loki-canary-crqpg 1/1 Running 0 10m loki-canary-hm26p 1/1 Running 0 10m loki-canary-v9wv9 1/1 Running 0 10m loki-chunks-cache-0 2/2 Running 0 10m loki-compactor-0 1/1 Running 0 10m loki-distributor-78ccdcc9b4-9wlhl 1/1 Running 0 10m loki-distributor-78ccdcc9b4-km6j2 1/1 Running 0 10m loki-distributor-78ccdcc9b4-ptwrb 1/1 Running 0 10m loki-gateway-5f97f78755-hm6mx 1/1 Running 0 10m loki-index-gateway-0 1/1 Running 0 10m loki-index-gateway-1 1/1 Running 0 10m loki-ingester-zone-a-0 1/1 Running 0 10m loki-ingester-zone-b-0 1/1 Running 0 10m loki-ingester-zone-c-0 1/1 Running 0 10m loki-querier-89d4ff448-4vr9b 1/1 Running 0 10m loki-querier-89d4ff448-7nvrf 1/1 Running 0 10m loki-querier-89d4ff448-q89kh 1/1 Running 0 10m loki-query-frontend-678899db5-n5wc4 1/1 Running 0 10m loki-query-frontend-678899db5-tf69b 1/1 Running 0 10m loki-query-scheduler-7d666bf759-9xqb5 1/1 Running 0 10m loki-query-scheduler-7d666bf759-kpb5q 1/1 Running 0 10m loki-results-cache-0 2/2 Running 0 10m loki-ruler-0 1/1 Running 0 10m
Loki 게이트웨이 서비스 찾기
Loki 게이트웨이 서비스는 Loki 게이트웨이를 인터넷에 노출하는 LoadBalancer 서비스입니다. 여기에서 로그를 쓰고 쿼리합니다. 기본적으로 NGINX가 게이트웨이로 사용됩니다.
주의: Loki 게이트웨이 서비스는 인터넷에 노출됩니다. 이 자습서에서는 사용자 이름과 암호를 사용하여 기본 인증을 제공합니다. 자세한 내용은 인증 설명서를 참조하십시오.
Loki 게이트웨이 서비스를 찾으려면 다음 명령을 실행하십시오.
kubectl get svc -n loki
외부 IP 주소가 있는 Loki 게이트웨이 서비스가 표시되어야 합니다. 이 주소는 Loki에 쓰고 쿼리하는 데 사용할 주소입니다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE loki-gateway LoadBalancer 10.100.201.74 12345678975675456-1433434453245433545656563.eu-west-2.elb.amazonaws.com 80:30707/TCP 46m
축하합니다! Helm 차트를 사용하여 AWS에 Loki를 성공적으로 배포했습니다. 마치기 전에 배포를 테스트해 보겠습니다.
Loki 배포 테스트
k6는 Loki 배포를 테스트하는 가장 빠른 방법 중 하나입니다. 이를 통해 Loki에 로그를 쓰고 쿼리할 수 있습니다. k6를 시작하려면 아래 단계를 따르십시오.
-
로컬 컴퓨터에 Loki 확장 기능이 있는 k6를 설치합니다. k6 및 xk6-loki 확장 기능 설치를 참조하십시오.
-
다음 내용으로
aws-test.js
파일을 만듭니다.import { sleep, check } from 'k6'; import loki from 'k6/x/loki'; /** * URL used for push and query requests * Path is automatically appended by the client * @constant {string} */ const username = '<USERNAME>'; const password = '<PASSWORD>'; const external_ip = '<EXTERNAL-IP>'; const credentials = `${username}:${password}`; const BASE_URL = `http://${credentials}@${external_ip}`; /** * Helper constant for byte values * @constant {number} */ const KB = 1024; /** * Helper constant for byte values * @constant {number} */ const MB = KB * KB; /** * Instantiate config and Loki client */ const conf = new loki.Config(BASE_URL); const client = new loki.Client(conf); /** * Define test scenario */ export const options = { vus: 10, iterations: 10, }; export default () => { // Push request with 10 streams and uncompressed logs between 800KB and 2MB var res = client.pushParameterized(10, 800 * KB, 2 * MB); // Check for successful write check(res, { 'successful write': (res) => res.status == 204, }); // Pick a random log format from label pool let format = randomChoice(conf.labels['format']); // Execute instant query with limit 1 res = client.instantQuery(`count_over_time({format="${format}"}[1m])`, 1); // Check for successful read check(res, { 'successful instant query': (res) => res.status == 200, }); // Execute range query over last 5m and limit 1000 res = client.rangeQuery(`{format="${format}"}`, '5m', 1000); // Check for successful read check(res, { 'successful range query': (res) => res.status == 200, }); // Wait before next iteration sleep(1); }; /** * Helper function to get random item from array */ function randomChoice(items) { return items[Math.floor(Math.random() * items.length)]; }
<EXTERNAL-IP>
를 Loki 게이트웨이 서비스의 외부 IP 주소로 바꾸십시오.이 스크립트는 Loki에 로그를 쓰고 Loki에서 로그를 쿼리합니다. 800KB에서 2MB 사이의 임의 형식으로 로그를 쓰고 지난 5분 동안 임의 형식으로 로그를 쿼리합니다.
-
테스트를 실행합니다.
./k6 run aws-test.js
이렇게 하면 테스트가 실행되고 결과가 출력됩니다. 테스트가 Loki에 로그를 쓰고 Loki에서 로그를 쿼리하는 것을 볼 수 있습니다.
이제 AWS에서 마이크로서비스 모드로 Loki를 성공적으로 배포했으므로 다음을 탐색할 수 있습니다.