안녕하세요?
AEWS 스터디 4주차 EKS Observability 과제 시작하겠습니다.
이번 주제는 Datadog Agent로 Traefik pod의 로그를 Datadog으로 전송하기 입니다.
테스트를 완료하면 아래와 같은 모습이 됩니다.
Kind를 이용한 K8S 클러스터 환경 준비
관련 필수 툴을 설치하겠습니다.
# Install Kind
brew install kind
kind --version
# Install kubectl
brew install kubernetes-cli
kubectl version --client=true
## kubectl -> k 단축키 설정
echo "alias kubectl=kubecolor" >> ~/.zshrc
# Install Helm
brew install helm
helm version
필요한 툴들도 설치해줍니다.
# 툴 설치
brew install krew
brew install kube-ps1
brew install kubectx
# kubectl 출력 시 하이라이트 처리
brew install kubecolor
echo "alias kubectl=kubecolor" >> ~/.zshrc
echo "compdef kubecolor=kubectl" >> ~/.zshrc
# krew 플러그인 설치
kubectl krew install neat stren
저는 Docker Desktop이 아니라 OrbStack으로 컨테이너들을 띄우고 있습니다.
관련 내용은 이 글을 참고해주시기 바랍니다.
Kind와 OrbStack를 사용해서 쉽게 Local에서 Kubernetes 사용하기
클러스터를 배포할 준비를 합니다.
# Create a cluster with kind
kind create cluster
# 클러스터 배포 확인
kind get clusters
myk8s
kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:26443
CoreDNS is running at https://127.0.0.1:26443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
# 노드 정보 확인
kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
myk8s-control-plane Ready control-plane 141d v1.30.0 192.168.247.2 <none> Debian GNU/Linux 12 (bookworm) 6.12.15-orbstack-00304-gd0ddcf70447d containerd://1.7.15
...
# 컨트롤플레인 (컨테이너) 노드 1대가 실행
docker ps
docker images
# kube config 파일 확인
cat ~/.kube/config
# 클러스터 삭제
kind delete cluster
진짜로 설정값을 넣어서 클러스터를 생성합니다.
kind create cluster --name myk8s --image kindest/node:v1.31.6 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- containerPort: 30002
hostPort: 30002
- containerPort: 30003
hostPort: 30003
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
controllerManager:
extraArgs:
bind-address: "0.0.0.0"
etcd:
local:
extraArgs:
listen-metrics-urls: "http://0.0.0.0:2381"
scheduler:
extraArgs:
bind-address: "0.0.0.0"
- |
kind: KubeProxyConfiguration
metricsBindAddress: "0.0.0.0"
EOF
kind get nodes --name myk8s
myk8s-control-plane
kubens default
Context "kind-myk8s" modified.
Active namespace is "default".
# kind 는 별도 도커 네트워크 생성 후 사용 : 기본값 172.18.0.0/16
docker network ls
NETWORK ID NAME DRIVER SCOPE
ff79b11006b5 bridge bridge local
91c12d651673 host host local
7a90578a3a56 kind bridge local
a2e20eeb2e52 none null local
625100f715de traefik-plugin-hands-on_default bridge local
docker inspect kind | jq
[
{
"Name": "kind",
"Id": "7a90578a3a56ec00898c824fa6b45706e85d8e5e64a9d489d2742e9c7bb580b7",
"Created": "2024-09-01T20:16:36.120864157+09:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": true,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.247.0/24",
"Gateway": "192.168.247.1"
...
kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:59701
CoreDNS is running at https://127.0.0.1:59701/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
# 노드 정보 확인 : CRI 는 containerd 사용
kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
myk8s-control-plane Ready control-plane 141d v1.30.0 192.168.247.2 <none> Debian GNU/Linux 12 (bookworm) 6.12.15-orbstack-00304-gd0ddcf70447d containerd://1.7.15
# 네임스페이스 확인 >> 도커 컨테이너에서 배운 네임스페이스와 다릅니다!
kubectl get namespaces
# 디버그용 내용 출력에 ~/.kube/config 권한 인증 로드
kubectl get pod -v6
I0225 21:29:32.387575 12488 loader.go:395] Config loaded from file: /Users/mokpolar/.kube/config
I0225 21:29:32.397525 12488 round_trippers.go:553] GET https://127.0.0.1:59701/api/v1/namespaces/default/pods?limit=500 200 OK in 5 milliseconds
No resources found in default namespace.
유용한 툴인 Kube-ops-view 도 설치해줍니다.
# kube-ops-view
# helm show values geek-cookbook/kube-ops-view
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=NodePort,service.main.ports.http.nodePort=30000 --set env.TZ="Asia/Seoul" --namespace kube-system
# 설치 확인
kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view
# kube-ops-view 접속 URL 확인 (1.5 , 2 배율)
open "http://127.0.0.1:30000/#scale=1.5"
open "http://127.0.0.1:30000/#scale=2"
Datadog Agent 준비
Datadog API Key 준비
아래 화면과 같이 Datadog Personal Settings에서 API Key, APP Key를 준비해둡니다.
Datadog Agent 설치
이제 클러스터에 Datadog Agent를 설치해줍니다.
먼저 Datadog을 Operator 패턴으로 배포해줍니다.
이 공식 문서를 참고 해주시기 바랍니다.
아래와 같이 values를 미리 준비한 뒤 설치합니다.
helm repo add datadog https://helm.datadoghq.com
helm show values datadog/datadog-operator > values.yaml
helm install -n mokpolar datadog-operator datadog/datadog-operator -f values.yaml
미리 준비해 둔 API, APP Key로 K8S Secret을 생성합니다.
물론 테스트가 아닌 프로덕션 환경에서는 보안상 이런 Key들은 Vault 등에 넣어두는 것이 좋습니다.
kubectl create secret generic datadog-secret --from-literal api-key=<DATADOG_API_KEY> --from-literal app-key=<DATADOG_APP_KEY>
Operator 형태로 배포했기 때문에
CR도 따로 배포해줘야 합니다.
secret을 생성한 것에 맞추어 아래와 같이 Datadog Agent도 배포해줍니다.
log 수집을 위해 logCollection도 활성화 해줍니다.
apiVersion: datadoghq.com/v2alpha1
kind: DatadogAgent
metadata:
name: datadogdatadi
namespace: mokpolar
spec:
global:
site: "datadoghq.com"
credentials:
apiSecret:
secretName: datadog-secret
keyName: api-key
features:
apm:
enabled: true
logCollection:
enabled: true
그러면 daemonset 형태로 Datadog agent가 배포됩니다.
아래 표에 안내된 사이트 URL 중에서 내 Datadog 웹사이트 URL과 동일한 것을 찾아 어떤 사이트에 있는지 확인할 수 있습니다.
사이트 | 사이트 URL | 사이트 파라미터 | 위치 |
---|---|---|---|
US1 | https://app.datadoghq.com |
datadoghq.com |
US |
US3 | https://us3.datadoghq.com |
us3.datadoghq.com |
US |
US5 | https://us5.datadoghq.com |
us5.datadoghq.com |
US |
EU1 | https://app.datadoghq.eu |
datadoghq.eu |
유럽연합(독일) |
US1-FED | https://app.ddog-gov.com |
ddog-gov.com |
US |
AP1 | https://ap1.datadoghq.com |
ap1.datadoghq.com |
일본 |
Traefik 준비
이번 테스트는 Traefik에서 나오는 로그를 Datadog으로 전송하여 확인하는 것입니다.
앞선 글에서 Traefik의 데이터 전송구조를 살펴 본 적이 있습니다. 참고 부탁드립니다.
Traefik API Gateway 사용시 AWS EKS의 NLB에서 Backend까지의 Flow
Traefik의 설치는 아래와 같은 방식으로 진행합니다.
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik
이번에는 Traefik 설치 시 datadog agent로 metric 데이터를 전송하기 위해 설정을 바꿔줍니다.
아래와 같은 형태입니다.
datadog:
## address는 datadog-agent에 메트릭을 전송하도록 지시합니다.
## address에서는 datadog agent의 내부 주소를 작성합니다.
address: "http://datadog-agent.mokpolar.svc.cluster.local:8125" #"127.0.0.1:8125"
## 메트릭을 datadog-agent에 푸시하는 데 사용되는 간격. 기본값=10s
pushInterval: 10s
## 메트릭 수집에 사용할 접두사. 기본값="traefik"
prefix: traefik
## 엔트리 포인트에 메트릭을 활성화합니다. 기본값=true
addEntryPointsLabels: true
## 라우터에 메트릭을 활성화합니다. 기본값=false
addRoutersLabels: true
## 서비스에 메트릭을 활성화합니다. 기본값=true
addServicesLabels: true
Traefik 에서 로그 남기기
배포된 Traefik pod에서 원하는 로그를 남기기 위해서는
Custom Plugin으로 Traefik의 플러그인 코드를 일부 수정할 수 있습니다.
GitHub - traefik/plugindemo: This repository includes an example plugin, for you to use as a reference for developing your own plugins
위의 Repo를 참고하여 plugin 코드를 일부 수정해주겠습니다.
위 Repo의 README에 나와있듯이, 아래와 같은 파일 구조에서 demo.go의 내용을 일부 수정해주면 됩니다.
./plugins-local/
└── src
└── github.com
└── traefik
└── plugindemo
├── demo.go
├── demo_test.go
├── go.mod
├── LICENSE
├── Makefile
└── readme.md
대신에 호출이 들어올 때 마다 로그를 남기도록 아래와 같은 부분을 추가해주면 됩니다.
MyLogger := log.New(os.Stdout, "MYLOG: ", log.LstdFlags)
MyLogger.Print("This is print stdout from logger")
혹은 더 쉬운 방법으로 그냥 기존에 있는 Plugin을 사용해서 배포해볼 수도 있습니다.
Plugins로 접근해서 API Key Auth by Septima를 사용해봅니다.
plugin을 적용하고 Middleware에 API Key를 박은 뒤 호출해봅니다.
Traefik을 다시 배포 한 뒤
Traefik pod에 로그가 남도록 호출해줍니다.
curl -X POST \
-H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXX" \
"http://localhost:9898/vector" \
-d "{\"message\": \"timestamp:, random\"}"
아래와 같은 구조가 됩니다.
그러면 Traefik pod에는 이런 로그가 Traefik pod에 남는걸 볼 수 있습니다.
그러면 Datadog 화면에서도 해당 로그를 확인해볼 수 있습니다.
References
'Kubernetes' 카테고리의 다른 글
Mountpoint for Amazon S3로 EKS Pod에 S3 mount하기 (0) | 2025.02.18 |
---|---|
Traefik API Gateway 사용시 AWS EKS의 NLB에서 Backend까지의 Flow (0) | 2025.02.16 |
ECR Pull Through Cache를 써서 Private ECR에 Container Image 넣기 (4) | 2025.02.06 |
AWS VPC CNI 공부하기 (1) | 2024.11.02 |
Cilium CNI 공부하기 (3) | 2024.10.25 |