상세 컨텐츠

본문 제목

kube-burner measurement 테스트

> Tech

by Ryusstory 2025. 8. 30.

본문

 

이전 kube-burner 소개 글에 이어서 조금 활용해보고자 하는 마음으로 작성하기 시작했다.

테스트를 하면서 느낀 점은 다른 테스트 도구를 찾는 것이 좋아보인다.
kube-burner는 오픈소스 이지만 kube-burner-ocp라고 해서 openshift에서 사용하기 위한 래핑된 도구가 있는데, 이를 위한 맛보기 도구 정도로 느껴졌다.

kube-burner의 example안에도 openshift 관련 내용이 좀 남아있어서 openshift의 도구 맛보기... 정도로 느껴지기도 했고, kube-burner-ocp 툴을 보면 같은 목적의 도구임에도 확실히 완성도가 달라보였다.

결과적으로 테스트 했을 때 예전에 테스트했던 Artillery나 ngrinder와 같은 정도의 만족도를 느끼기도 어려워서 다시 사용하지는 않을 것 같고, 벤더에서 작업하는 오픈소스 자체도 좀 거리감을 둬야겠다는 생각이 든다.

환경 구성

kind 클러스터 삭제 & 설치

POD_CIDR="10.244.0.0/24"
SERVICE_CIDR="10.96.0.0/12"
set -euo pipefail
echo -e "\033[1,33m --- DELETE CLUSTER \033[0m"
kind delete cluster
echo -e "\033[1,33m --- CREATE CLUSTER \033[0m"
kind create cluster --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
  - containerPort: 30004
    hostPort: 30004
  kubeadmConfigPatches: # Prometheus Target connection refused bind-address 설정
  - |
    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
  - |
    kind: KubeletConfiguration
    maxPods: 65535
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        pod-cidr: 10.0.0.0/16  # Explicitly set the podCIDR for the node
networking:
  podSubnet: $POD_CIDR
  serviceSubnet: $SERVICE_CIDR
  disableDefaultCNI: true
EOF

cilium CNI 설치

cilium CNI를 설치하고 진행을 했는데, 위의 disableDefaultCNI: true를 주석으로 처리하면 별도 CNI를 설치안해도 kindnet을 사용 할 수 있다.

helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium --namespace kube-system --version 1.18.1 -f - <<EOF
ipam:
  mode: cluster-pool
  operator:
    clusterPoolIPv4PodCIDRList: ["172.20.0.0/16"]
hubble:
  enabled: true
  relay:
    enabled: true
  ui:
    enabled: true
operator:
  replicas: 1
EOF

metric-server, prometheus stack 설치

아래처럼 설치 후에 접속이 가능한지 확인한다.
http://localhost:30001/
http://localhost:30002/

대시보드는 pod 수를 보거나 할 경우 아래 두개 정도가 좋은 것같다.
https://grafana.com/grafana/dashboards/22523-eks-dashboard/
https://grafana.com/grafana/dashboards/15661-k8s-dashboard-en-20250125/

계정은 admin:prom-operator 이다.

helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm upgrade --install metrics-server metrics-server/metrics-server --set 'args[0]=--kubelet-insecure-tls' -n kube-system

echo -e "\033[1,33m --- INSTALL PROMETHEUS \033[0m"
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 77.0.2 \
  --create-namespace --namespace monitoring -f - <<EOF
prometheus:
  prometheusSpec:
    scrapeInterval: 15s
    evaluationInterval: 15s
  service:
    type: NodePort
    nodePort: 30001
grafana:
  defaultDashboardsTimezone: Asia/Seoul
  adminPassword: prom-operator
  service:
    type: NodePort
    nodePort: 30002
alertmanager:
  enabled: false
defaultRules:
  create: false
prometheus-windows-exporter:
  prometheus:
    monitor:
      enabled: false
EOF

opensearch 설치

예시에 opensearch에서 볼 수 있는 정보가 있다길래 설치해봤다.

opensearchopensearch-dashboard 를 통해 설치했다.

opensearch가 생각보다 골치 아팠는데, https를 끄면 admin password가 제대로 동작하지 않아서 한참 삽질하다가 아래처럼 뭔가 구성은 했는데,
opensearch-dashboard에서 opensearch로 로그인이 안된다. 등등 삽질을 하다가 opensearch의 docker-compose 설명을 보니 매우 명쾌했다..
docker-compose를 더 선호하는 것으로 보인다. 해당 설정으로 helm으로 옮겨와서 진행했다.

설치후에 접속해서 잘 열리는 지 확인한다. 켜지는데 시간이 좀 걸리긴 한다.
http://localhost:30001/
http://localhost:30002/

echo -e "\033[1,33m --- INSTALL PROMETHEUS \033[0m"
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 77.0.2 \
  --create-namespace --namespace monitoring -f - <<EOF
prometheus:
  prometheusSpec:
    scrapeInterval: 15s
    evaluationInterval: 15s
  service:
    type: NodePort
    nodePort: 30001
grafana:
  defaultDashboardsTimezone: Asia/Seoul
  adminPassword: prom-operator
  service:
    type: NodePort
    nodePort: 30002
alertmanager:
  enabled: false
defaultRules:
  create: false
prometheus-windows-exporter:
  prometheus:
    monitor:
      enabled: false
EOF

echo -e "\033[1,33m --- INSTALL OPENSEARCH \033[0m"
helm repo add opensearch https://opensearch-project.github.io/helm-charts/
helm repo update
helm install os opensearch/opensearch -f - <<EOF
singleNode: true
service:
  type: NodePort
  nodePort: 30003
config:
  opensearch.yml: |
    network.host: 0.0.0.0
    cluster.name: opensearch-cluster
protocol: http
extraEnvs:
  - name: DISABLE_INSTALL_DEMO_CONFIG
    value: "true"
  - name: DISABLE_SECURITY_PLUGIN
    value: "true"
EOF

kube-burner measurements, opensearch 연동 확인

전체적인 sample도 그렇고 내용이 openshift 관련한 내용이 많은 것 같아 조금 애매했지만 일단 동작 자체는 확인해보기로 했다.
사실 진행은 했지만... burner로 테스트는 진행하고 일반적인 k8s 모니터링 대시보드를 볼 것 같고, 테스트의 P99, P95 같은 값을 확인하는 목적이 아니라면 딱히 사용하지는 않을 것 같다.
그리고 local 파일로도 뽑을 수는 있어서, production performance 테스트를 연동하거나 할 경우가 아니면 꼭 opensearch를 쓸 필요는 없을 것 같다.

아무튼 아래 설정으로 설치하면 아래 처럼 접속되는걸 확인할 수 있다.

http://localhost:30003/
http://localhost:30004/

아래 설정 정리전에 사용한 성공한 설정값을 먼저 정리하면 아래와 같다

metricsEndpoints:
- indexer:
    type: local
    metricsDirectory: metrics2
- indexer:
    esServers: [http://localhost:30003]
    insecureSkipVerify: true
    defaultIndex: kb-value
    type: elastic
global:
  gc: true
  measurements:
  - name: podLatency

작은 팁 gc와 uuid를 통한 리소스 정리

gc를 추가하면 테스트가 끝나면 바로 kube-burner가 정리를 해준다.

global:
  gc: true

그게 아니라면 테스트가 시작하거나 끝날 때 로그에 항상 UUID가 표현되는데, uuid로 삭제 할 수 있는 기능이 있어서 이렇게 지우면 편하다.

kube-burner destroy --uuid 031bfa69-ad1e-4f67-89f0-58d81f23df55

추가로, 생성에도 uuid를 직접 지정할 수 있어서 아래처럼 uuid를 지정해서 추가/삭제에 활용할 수 있다

kube-burner create -f kb-create.yaml --uuid=testtest
...
kube-burner destroy --uuid=testtest

measurements 설정

global 설정 아래에 measurements를 설정하면 해당 지표가 수집된다.

global:
  measurements:
  - name: podLatency
  - name: jobLatency

podLatency

podlatency에서는 각각의 pod의 요청부터 준비완료까지의 지연시간을 측정하는걸 볼 수 있다.
아래는 metricName을 보면 podLatencyQuantiles고, 이거 외에도 podLatency 측정값도 같이 들어온다.
quantileName 관련해서도 공식 문서에는 아래처럼 설명이 나와있고, 자세하진 않지만 공식문서에 어느정도 설명이 나와있다.

  • PodScheduled: Pod가 노드에 스케쥴됨.
  • PodReadyToStartContainers: Pod 샌드박스가 성공적으로 생성되었고 네트워킹이 구성됨.
  • Initialized: Pod의 모든 init 컨테이너가 성공적으로 시작됨.
  • ContainersReady: 포드에 있는 모든 컨테이너가 준비됨.
  • Ready: 포드는 요청을 처리 가능하고, 모든 서비스의 부하 분산 풀에 추가됨.

jobLatency

jobLatency는 전체 job에 대해서 하나의 레코드만 생성된다. 어떤 설정값으로 테스트 했는지, QPS가 어느정도로 측정됐는지, 걸린 시간 정도가 유의미한 값으로 보인다. 한번 보고자 해서 넣었지만 podLatency만 보면 될 것 같다.

metricEndpoints 설정

local

아래 설정을 사용하면 metrics 폴더를 생성하고 해당 폴더에 json으로 측정된 값들을 저장한다.

metricsEndpoints:
  - indexer:
      metricsDirectory: metrics
      type: local

테스트 후에 폴더를 확인해보면 이런식으로 저장된다.

opensearch

아래처럼 설정하면 된다.
endpoint는 prometheous의 주소, esServer는 opensearch의 주소를 넣으면 되고, 테스트별로 결과를 따로 보고 싶다면 defaultIndex를 수정해주거나 하면 된다.

metricsEndpoints:
- indexer:
    esServers: [http://localhost:30003]
    insecureSkipVerify: true
    defaultIndex: kb12
    type: elastic

확인방법

메트릭이 들어오면
http://localhost:30004/app/opensearch_index_management_dashboards#/indices와 같은 주소나 Index Management의 Indexes에서 들어온 데이터를 확인할 수 있고,
http://localhost:30004/app/management/opensearch-dashboards/indexPatterns/create와 같은 주소나 Dashboard Management의 Index Patterns에서 Create Index Pattern로 들어가서 index를 선택해서 만들어주면, discover에서 확인할 수 있다.

example 테스트

원래는 별도로 테스트를 만들어 보려고 했으나 opensearch와 measurement 삽질을 너무 많이해서 지쳐서 example만 두개 돌려보고 끝내려고 한다.
kube-burner 레포를 clone해서 작업했다.

kube-burner workload example에 가보면 돌려볼 만한게, 간단한 웹서버와 curl을 수행하는 테스트인 kubelet-density-cni와 cloud-bulldozer/perfapp를 사용해서 postgresql와 연결되는 테스트인 kubelet-density-heavy정도로 보였다.

kubelet-density-cni

구축해 놨으니... measurements 부분을 추가하고

metricsEndpoints:
- endpoint: http://localhost:30001
  alias: local-indexer
  indexer:
    type: local
    metricsDirectory: metrics
- endpoint: http://localhost:30001
  alias: opensearch
  indexer:
    esServers: [http://localhost:30003]
    insecureSkipVerify: true
    defaultIndex: kubelet-density-cni
    type: elastic

워커 노드를 같이 구성했다면 그대로 돌리면 되지만 control 노드만 구성해서 테스트 중이라면
deployments에 포함된 nodeSelector를 삭제해주고 돌리면 된다.
그리고 preLoadPeriod를 초단위로 내려준다면 좀 더 빠르게 시작할 수 있다 (설정된 값은 2분)

테스트를 진행하고 값을 봤는데, podReadyLatency정도만 의미가 있어 보여서 jobIteration을 X축으로 하고, Y축을 podReadyLatency로 설정해서 시각화를 해봤다.

kubelet-density-cni

앞의 내용과 동일하게 metricsEndpoints를 추가하고, nodeSelector를 삭제하고 진행했다.

위 테스트와 동일하게 jobIteration을 X축으로 하고, Y축을 podReadyLatency로 설정해서 시각화를 해봤다.

툴이 마음에 들었다면 이것저것 더 해보고 싶었겠지만.. 툴이 만족스럽지 못해서 이정도만 테스트해보고 접기로 했다..

테스트용 스크립트 정리

init.sh

#!/bin/bash
POD_CIDR="10.244.0.0/24"
SERVICE_CIDR="10.96.0.0/12"
set -euo pipefail
echo -e "\033[1,33m --- DELETE CLUSTER \033[0m"
kind delete cluster
echo -e "\033[1,33m --- CREATE CLUSTER \033[0m"
kind create cluster --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
  - containerPort: 30004
    hostPort: 30004
  - containerPort: 30005
    hostPort: 30005
  - containerPort: 30006
    hostPort: 30006
  kubeadmConfigPatches: # Prometheus Target connection refused bind-address 설정
  - |
    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
  - |
    kind: KubeletConfiguration
    maxPods: 65535
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        pod-cidr: 10.0.0.0/16  # Explicitly set the podCIDR for the node
networking:
  podSubnet: $POD_CIDR
  serviceSubnet: $SERVICE_CIDR
  disableDefaultCNI: true
EOF
echo -e "\033[1,33m --- INSTALL CILIUM \033[0m"
helm repo add cilium https://helm.cilium.io/
helm repo update
helm install cilium cilium/cilium --namespace kube-system --version 1.18.1 -f - <<EOF
ipam:
  mode: cluster-pool
  operator:
    clusterPoolIPv4PodCIDRList: ["172.20.0.0/16"]
hubble:
  enabled: true
  relay:
    enabled: true
  ui:
    enabled: true
operator:
  replicas: 1
EOF

echo -e "\033[1,33m --- INSTALL METRIC-SERVER \033[0m"
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm upgrade --install metrics-server metrics-server/metrics-server --set 'args[0]=--kubelet-insecure-tls' -n kube-system

echo -e "\033[1,33m --- INSTALL PROMETHEUS \033[0m"
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 77.0.2 \
  --create-namespace --namespace monitoring -f - <<EOF
prometheus:
  prometheusSpec:
    scrapeInterval: 15s
    evaluationInterval: 15s
  service:
    type: NodePort
    nodePort: 30001
grafana:
  defaultDashboardsTimezone: Asia/Seoul
  adminPassword: prom-operator
  service:
    type: NodePort
    nodePort: 30002
alertmanager:
  enabled: false
defaultRules:
  create: false
prometheus-windows-exporter:
  prometheus:
    monitor:
      enabled: false
EOF

echo -e "\033[1,33m --- INSTALL OPENSEARCH \033[0m"
helm repo add opensearch https://opensearch-project.github.io/helm-charts/
helm repo update
helm install os opensearch/opensearch -f - <<EOF
singleNode: true
service:
  type: NodePort
  nodePort: 30003
config:
  opensearch.yml: |
    network.host: 0.0.0.0
    cluster.name: opensearch-cluster
protocol: http
extraEnvs:
  - name: DISABLE_INSTALL_DEMO_CONFIG
    value: "true"
  - name: DISABLE_SECURITY_PLUGIN
    value: "true"
EOF

echo -e "\033[1,33m --- INSTALL OPENSEARCH DASHBOARDS (OPTIONAL FOR VISUALIZATION) \033[0m"
helm install os-dashboards opensearch/opensearch-dashboards -f - <<EOF
service:
  type: NodePort
  nodePort: 30004
opensearchHosts: "http://opensearch-cluster-master:9200"
extraEnvs:
  - name: DISABLE_SECURITY_DASHBOARDS_PLUGIN
    value: "true"
EOF

kb-create-os.yaml

opensearch 연동 테스트용 kube-burner 설정

metricsEndpoints:
- endpoint: http://localhost:30001
  alias: local-indexer
  indexer:
    type: local
    metricsDirectory: metrics2
- endpoint: http://localhost:30001
  alias: opensearch
  indexer:
    esServers: [http://localhost:30003]
    insecureSkipVerify: true
    defaultIndex: kb-value
    type: elastic
  metrics:
  - metrics-profile.yaml
global:
  gc: true
  measurements:
  - name: podLatency
jobs:
- name: create-deployments
  preLoadPeriod: 10s
  qps: 500
  burst: 500
  namespace: kb-test
  jobIterations: 10
  objects:
  - objectTemplate: kb-deployment.yaml
    replicas: 3

 

kb-deployment.yaml

위 설정에 사용되는 템플릿

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment-{{ .Iteration }}-{{ .Replica }}  # 동적 이름 설정
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-{{ .Iteration }}-{{ .Replica }}  # 라벨도 동기화
  template:
    metadata:
      labels:
        app: test-{{ .Iteration }}-{{ .Replica }}
    spec:
      containers:
      - name: nginx
        image: nginx:latest

 

'> Tech' 카테고리의 다른 글

K8s 테스트용 3tier sample  (0) 2025.09.05
kube-burner 툴 소개  (0) 2025.08.28
cilium mtls example test 1차 실패  (0) 2025.08.23

관련글 더보기