Kubernetes API Server는 클러스터의 핵심 구성요소로 사용자의 Request를 전달 받아 API Resource 를 생성, 수정, 삭제, 조회하는 일을 수행합니다. 이번 블로그에서는 K8S API Server에 부하를 발생하여 성능을 측정하거나, 여러가지 장애상황을 재현해보겠습니다.
0. 실습환경 구성
- Rocky Linux 9.6 (커널버전 : 5.14.0-570.26.1.el9_6.x86_64)
- K8S 클러스터는 kind를 이용
| # Prometheus Target connection refused bind-address 설정 : kube-controller-manager , kube-scheduler , etcd , kube-proxy kind create cluster --name myk8s --image kindest/node:v1.33.2 --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: # 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
Creating cluster "myk8s" ... ✓ Ensuring node image (kindest/node:v1.33.2) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-myk8s" You can now use your cluster with: kubectl cluster-info --context kind-myk8s Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/ # 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=30003 --set env.TZ="Asia/Seoul" --namespace kube-system NAME: kube-ops-view LAST DEPLOYED: Fri Aug 29 09:23:05 2025 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: 1. Get the application URL by running these commands: export NODE_PORT=$(kubectl get --namespace kube-system -o jsonpath="{.spec.ports[0].nodePort}" services kube-ops-view) export NODE_IP=$(kubectl get nodes --namespace kube-system -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT # open "http://localhost:30003/#scale=1.5" ![]() # metrics-server 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 NAME: metrics-server LAST DEPLOYED: Fri Aug 29 09:25:39 2025 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: *********************************************************************** * Metrics Server * *********************************************************************** Chart version: 3.13.0 App version: 0.8.0 Image tag: registry.k8s.io/metrics-server/metrics-server:v0.8.0 *********************************************************************** # 확인 kubectl top node NAME STATUS ROLES AGE VERSION myk8s-control-plane Ready control-plane 4m49s v1.33.2 kubectl top pod -A --sort-by='cpu' NAMESPACE NAME CPU(cores) MEMORY(bytes) kube-system kube-apiserver-myk8s-control-plane 25m 202Mi kube-system etcd-myk8s-control-plane 14m 31Mi kube-system kube-controller-manager-myk8s-control-plane 10m 56Mi kube-system kube-ops-view-6658c477d4-rrgwh 7m 31Mi kube-system kube-scheduler-myk8s-control-plane 7m 22Mi kube-system metrics-server-5dd7b49d79-77jql 3m 19Mi kube-system coredns-674b8bbfcf-5gbkt 1m 17Mi kube-system coredns-674b8bbfcf-w4b4q 1m 17Mi kube-system kindnet-rj6x5 1m 10Mi kube-system kube-proxy-ndlnp 1m 17Mi local-path-storage local-path-provisioner-7dc846544d-m5m59 1m 9Mi kubectl top pod -A --sort-by='memory' NAMESPACE NAME CPU(cores) MEMORY(bytes) kube-system kube-apiserver-myk8s-control-plane 27m 202Mi kube-system kube-controller-manager-myk8s-control-plane 11m 56Mi kube-system kube-ops-view-6658c477d4-rrgwh 9m 31Mi kube-system etcd-myk8s-control-plane 14m 31Mi kube-system kube-scheduler-myk8s-control-plane 6m 22Mi kube-system metrics-server-5dd7b49d79-77jql 4m 20Mi kube-system coredns-674b8bbfcf-5gbkt 1m 17Mi kube-system coredns-674b8bbfcf-w4b4q 1m 17Mi kube-system kube-proxy-ndlnp 1m 17Mi kube-system kindnet-rj6x5 1m 10Mi local-path-storage local-path-provisioner-7dc846544d-m5m59 1m 9Mi |
- prometheus-stack 설치 by helm
| # 파라미터 파일 생성 cat <<EOT > monitor-values.yaml 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 EOT 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 75.15.1 \ -f monitor-values.yaml --create-namespace --namespace monitoring # 웹 접속 실행 - prometheus # http://127.0.0.1:30001 ![]() # 웹 접속 실행 - grafana ( admin / prom-operator ) # http://127.0.0.1:30002 ![]() # 대시보드 추가 - K8S new : 15661 - K8S API old : 12006 ![]() |
1. K8S API Server
K8S 클러스터를 관통하는 2가지의 용어는 아래와 같이 요약할 수 있을거 같습니다.
- Desigred State
- Declarative
K8S 클러스터는 사용자가 요청한 Desigred State를 Declarative 하게 선언만 하면, 그 후의 뒷단의 일은 K8S 구성요소가 알아서 Desigred State를 만족하려고 노력합니다.
위와 같은 작업을 하기 위해 "Hub and Spoke" 패턴을 이용합니다.


위 그림에서 볼수 있듯이 API Server 가 Hub가 되어다른 구성요소와 watch 메커니즘을 이용하여, Desigred State를 만족하기 위해 동작하기 때문에 API 서버의 부하가 집중되는 구조입니다.
kubectl 동작 이해하기
"kubectl get pod -A" 명령을 수행하면 K8S API Server와 인증 및 REST 통신을 하게 됩니다.
| kubectl get po -A -v 6 I0829 10:01:40.041838 174498 loader.go:402] Config loaded from file: /root/.kube/config I0829 10:01:40.042205 174498 envvar.go:172] "Feature gate default state" feature="ClientsAllowCBOR" enabled=false I0829 10:01:40.042227 174498 envvar.go:172] "Feature gate default state" feature="ClientsPreferCBOR" enabled=false I0829 10:01:40.042231 174498 envvar.go:172] "Feature gate default state" feature="InformerResourceVersion" enabled=false I0829 10:01:40.042236 174498 envvar.go:172] "Feature gate default state" feature="InOrderInformers" enabled=true I0829 10:01:40.042239 174498 envvar.go:172] "Feature gate default state" feature="WatchListClient" enabled=false I0829 10:01:40.054029 174498 round_trippers.go:632] "Response" verb="GET" url="https://127.0.0.1:45559/api/v1/pods?limit=500" status="200 OK" milliseconds=9 NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-674b8bbfcf-5gbkt 1/1 Running 0 39m kube-system coredns-674b8bbfcf-w4b4q 1/1 Running 0 39m kube-system etcd-myk8s-control-plane 1/1 Running 0 40m kube-system kindnet-rj6x5 1/1 Running 0 39m kube-system kube-apiserver-myk8s-control-plane 1/1 Running 0 39m kube-system kube-controller-manager-myk8s-control-plane 1/1 Running 0 39m kube-system kube-ops-view-6658c477d4-rrgwh 1/1 Running 0 38m kube-system kube-proxy-ndlnp 1/1 Running 0 39m kube-system kube-scheduler-myk8s-control-plane 1/1 Running 0 40m kube-system metrics-server-5dd7b49d79-77jql 1/1 Running 0 36m local-path-storage local-path-provisioner-7dc846544d-m5m59 1/1 Running 0 39m monitoring kube-prometheus-stack-grafana-7d9c86798d-gnjck 3/3 Running 0 30m monitoring kube-prometheus-stack-kube-state-metrics-684f8c7558-rcbks 1/1 Running 0 30m monitoring kube-prometheus-stack-operator-68589744f5-rlrkg 1/1 Running 0 30m monitoring kube-prometheus-stack-prometheus-node-exporter-bb2qj 1/1 Running 0 30m monitoring prometheus-kube-prometheus-stack-prometheus-0 2/2 Running 0 29m |
위의 호출 결과를 보면
- 먼저 kube config 파일을 읽어와 API Server와 클라이언트 인증서를 통한 인증(디폴트)을 통과한 후에
- POD 목록을 조회하는 GET 요청을 하고 있습니다.
Jmeter를 이용하여 부하발생을 위해서 "클라이언트 인증서"가 아닌 Bearear Token 을 이용한 인증을 이용하여 curl 명령으로 POD 목록을 조회하여 보겠습니다.
| # jmeter-sa 서비스어카운트 생성 kubectl create sa jmeter-sa serviceaccount/jmeter-sa created # 레거시 시크릿(Secret) 생성: # ServiceAccount에 바인딩될 kubernetes.io/service-account-token 유형의 시크릿을 생성 # 이 시크릿은 만료 기간이 없는 토큰을 포함하게 됩니다. kubectl apply -f - <<EOF apiVersion: v1
kind: Secret
metadata:
name: jmeter-sa-token
annotations:
kubernetes.io/service-account.name: jmeter-sa
type: kubernetes.io/service-account-token
secret/jmeter-sa-token created # 토큰 값 확인: 생성된 시크릿에서 실제 토큰 값을 Base64 디코딩하여 확인 kubectl get secret jmeter-sa-token -o jsonpath='{.data.token}' | base64 --decode eyJhbGciOiJSUzI1NiIsImtpZCI6IkJqUVhyV2o3c1JETWczZlZMQVpjendIcmxTWlZsQlA3bUJTNzJPbEN3dkEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImptZXRlci1zYS10b2tlbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJqbWV0ZXItc2EiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIyODAxMjZhNy03NWQxLTQ0YTYtYmJkYy1lNDAwYzUzNzJhZjkiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpqbWV0ZXItc2EifQ.p-EMrvuH9kVsWg1VtPdpsNqGTSUjja0AwQlNDHT0-yRLfiCOeY40rMDZCN0Lxn0T1mb8yw6SkC1CQTaZQHoZci8O7-sJE2yKJBKhdUzKufJt9kZ6sPsvUIVmxu5ymgG-RR73UqwWOWlBgh4oe8oDvbpOjr_fZBm1NTaOA7oc2oGeet3HboXMwtEtFB1JsUc12zRow7FmU_qBcTaa00TLfUAEj1kWle5Q1HAc_IaV-LOsedlA3Q1z1syu4GeNnlsOe2YAnQOA6fhZUXzJj8JK5ZNUxRoOoKDJrd9YMFnafYMEDlvnGjGgriFHlN4A-BHUCg2Y8YJLu_iz5_GvttVCEQ TOKEN=$(kubectl get secret jmeter-sa-token -o jsonpath='{.data.token}' | base64 --decode) # curl 명령을 이용한 POD 목록 조회 curl -k -H "Authorization: Bearer $TOKEN" https://127.0.0.1:45559/api/v1/pods "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion": "5534" }, "items": [ { "metadata": { "name": "coredns-674b8bbfcf-5gbkt", "generateName": "coredns-674b8bbfcf-", "namespace": "kube-system", ...(생략)... |
2. Jmeter
Jmeter 는 Java 기반의 오픈소스 부하도구로 다양한 프로토콜 및 플러그인을 지원하여 상용 부하테스트 도구가 할 수 있는 많은 부분을 대체하고 있습니다.
2.1. jmeter 설치
jmeter는 JAVA Runtime 환경이 있으면 실행이 가능합니다. 공식적으로 JAVA 8 이상을 요구합니다만, JAVA 17 이상을 추천하고 있습니다.
| # JAVA 버전 확인 java -version java version "24.0.2" 2025-07-15 Java(TM) SE Runtime Environment (build 24.0.2+12-54) Java HotSpot(TM) 64-Bit Server VM (build 24.0.2+12-54, mixed mode, sharing) # jmeter 다운로드 및 압축해제 wget https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.3.tgz tar xfz apache-jmeter-5.6.3.tgz ln -s apache-jmeter-5.6.3 jmeter # jmeter 실행 jmeter/bin/jmeter.sh > /dev/null 2>&1 & ![]() |
2.2. jmeter 를 이용한 POD 목록 조회 스크립트 작성
jmeter 는 부하스크립트를 코딩으로 하지 않고 아래와 같은 jmeter 블럭 구성요소를 계층적으로 구성하는 블록코딩 형식을 이용합니다.

HTTP Request Defaults 추가
- 모든 HTTP Request 의 디폴트 값 설정
- Test Plan -> Config Element -> HTTP Request Defaults
- 여기에서는 K8S API Server 의 프로토콜, IP, PORT 를 아래와 같이 설정

User Defined Variables 추가
- 사용자 정의 변수 이용 -> 이번 실습에서는 API Server TOKEN 값을 변수로 저장하여 사용합니다.
- Test Plan -> Config Element -> HTTP Request Defaults

Thread Group 추가
- Jmeter는 가상유저를 JAVA Thread를 이용합니다.
- Test Plan -> Threads (Users) -> Thread Group

View Results Tree 리스너 추가
- View Results Tree 리스너는 HTTP Request와 Response 내용을 관찰하고 디버깅 용도로 사용합니다.
- Thread Group -> Listener -> View Results Tree

Transaction Controller 추가
- Transaction Controller 구성요소는 TPS 를 측정하는 구성요소 입니다.
- Thread Group -> Logic Controller -> Transaction Controller
- 추가 후 "Generate parent sample" 을 체크합니다.

HTTP Request 샘플러 추가
- 샘플러 종류는 실제 Request를 수행하는 구성요소 입니다.
- Thread Group -> Transaction Controller -> Sampler -> HTTP Request
- path 항목에 POD 목록 조회하는 Endpoint 주소를 기입합니다.
- /api/v1/pods
- path 항목에 POD 목록 조회하는 Endpoint 주소를 기입합니다.

HTTP Header Manager 추가
- http 프로토콜의 Header 정보를 관리하는 구성요소입니다. 여기에서는 TOKEN 정보를 기입합니다.
- HTTP Request -> Config Element -> HTTP Header Manager

부하테스트
- 1명의 가상유저로 POD 목록 조회하는 Request 1회 호출
- 툴바의 ▶ (start)버튼 클릭
- View Resutl Tree 구성요소의 Request, Reponse 정보를 확인해 보면 POD 목록이 json 형태로 리턴된것을 볼 수 있습니다.

지금까지의 Jmeter 스크립트 파일을 아래에 첨부하였습니다.
2.3. jmeter 플러그인 설치
jmeter 는 플러그인 아키텍처를 이용합니다. 그래서 새로운 IT 기술에 대응하는 플러그인이 다양하게 존재합니다.
부하량을 제어하고 다양한 리스너를 이용하기위해서 플러그인을 설치해 보겠습니다.
- 플러그인 사이트
JMeter Plugins :: JMeter-Plugins.org
jmeter-plugins.org
# 플러그인 매니저 다운로드![]() wget -O jmeter/lib/ext/jmeter-plugins-manager-1.11.jar https://repo1.maven.org/maven2/kg/apc/jmeter-plugins-manager/1.11/jmeter-plugins-manager-1.11.jar # jmeter 재시작 ![]() # 플러그인 매니저 시작 ![]() # 플러그인 설치 # jpgc - Standard Set # vdn@github - pacing-jmeter-plugin ![]() |
부하량 제어 및 Test Plan 구조화
부하량 제어
- 부하량을 제어 하지 않으면 Request 를 보내고, Response 를 받은후 바로 또다시 Request를 보내기 때문에 순간적으로 과부하가 발생하게 됩니다.
- 그래서 부하테스트 도구들을 Pacing Time 이라는 개념을 이용해서 몇초에 한번씩 Request를 보낼지 설정하여 과부하를 방지하고, 더욱 중요한것은 단위시간당 원하는 부하량을 제어 할 수 있습니다.
- 아래 링크를 참조해서 POD 목록 조회하는 부하를 1초에 한번으로 조정합니다.
GitHub - vdaburon/pacing-jmeter-plugin: Add notion of Pacing for Apache JMeter
Add notion of Pacing for Apache JMeter. Contribute to vdaburon/pacing-jmeter-plugin development by creating an account on GitHub.
github.com

기능이 강화된 Listener 추가
부하 발생후 모니터링을 위해 아래 Listener 를 추가합니다.
- Test Plan -> Listener ->
- jp@gc - Active Threads Over Time
- jp@gc - Response Times Over Time
- jp@gc - Transactions per Second
- Summary Report

Test Fragment 추가
- Test Fragment 구성요소는 Test Plan을 구조화 하는 용도로 사용합니다.
- Test Plan -> Test Fragment -> Test Fragment

Test Plan 구조화
지금까지 작업한 구성요소의 이름을 수정하고 Test Fragement 를 이용하여 아래와 같은 모습으로 구조화 합니다.

부하량 조정
"TG_POD 조회" Thread Group 의 설정을 아래와 같이 조정합니다.

10 명의 가상유저가 60초동안 점진적으로 증가시키고 300초 동안 부하를 발생
부하 테스트 시작
- 툴바의 ▶ (start)버튼 클릭하고 각종 리스너의 그래프 및 그라파나 패널 모니터링
가상유저

응답시간

TPS


그라파나 대시보드 - Kubernetes apiserver

2.4. jmeter 를 이용한 POD 생성 스크립트 작성
kubectl 을 이용하여 POD를 생성할때 API 서버에 POST 방식으로 어떤 JSON 정보가 전달되는지 확인해 보겠습니다.
| # 명령행으로 my-pod 생성하고 POST 방식으로 전달되는 JSON 정보 확인 kubectl run my-pod --image=registry.k8s.io/pause:3.9 -v 8 I0829 12:56:20.177284 179852 loader.go:402] Config loaded from file: /root/.kube/config I0829 12:56:20.177413 179852 envvar.go:172] "Feature gate default state" feature="ClientsAllowCBOR" enabled=false I0829 12:56:20.177423 179852 envvar.go:172] "Feature gate default state" feature="ClientsPreferCBOR" enabled=false I0829 12:56:20.177428 179852 envvar.go:172] "Feature gate default state" feature="InformerResourceVersion" enabled=false I0829 12:56:20.177432 179852 envvar.go:172] "Feature gate default state" feature="InOrderInformers" enabled=true I0829 12:56:20.177436 179852 envvar.go:172] "Feature gate default state" feature="WatchListClient" enabled=false I0829 12:56:20.179835 179852 helper.go:246] "Request Body" body=< {"kind":"Pod","apiVersion":"v1","metadata":{"name":"my-pod","creationTimestamp":null,"labels":{"run":"my-pod"}},"spec":{"containers":[{"name":"my-pod","image":"registry.k8s.io/pause:3.9","resources":{}}],"restartPolicy":"Always","dnsPolicy":"ClusterFirst"},"status":{}} > I0829 12:56:20.179893 179852 round_trippers.go:527] "Request" verb="POST" url="https://127.0.0.1:45559/api/v1/namespaces/default/pods?fieldManager=kubectl-run" headers=< Accept: application/json, */* Content-Type: application/json User-Agent: kubectl/v1.33.4 (linux/amd64) kubernetes/74cdb42 > I0829 12:56:20.191233 179852 round_trippers.go:632] "Response" status="201 Created" headers=< Audit-Id: 8cbf45b0-ed66-4f28-83af-e5d8e352a043 Cache-Control: no-cache, private Content-Length: 2019 Content-Type: application/json Date: Fri, 29 Aug 2025 03:56:20 GMT X-Kubernetes-Pf-Flowschema-Uid: 9ab9faed-f679-4867-840e-5300ce24dfed X-Kubernetes-Pf-Prioritylevel-Uid: 3580616c-532a-4a2d-9fee-4fd4f2bcf96c > milliseconds=11 I0829 12:56:20.191318 179852 helper.go:246] "Response Body" body="{\"kind\":\"Pod\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"my-pod\",\"namespace\":\"default\",\"uid\":\"d760e73b-d72c-426c-92dc-7170b6bb6418\",\"resourceVersion\":\"18115\",\"generation\":1,\"creationTimestamp\":\"2025-08-29T03:56:20Z\",\"labels\":{\"run\":\"my-pod\"},\"managedFields\":[{\"manager\":\"kubectl-run\",\"operation\":\"Update\",\"apiVersion\":\"v1\",\"time\":\"2025-08-29T03:56:20Z\",\"fieldsType\":\"FieldsV1\",\"fieldsV1\":{\"f:metadata\":{\"f:labels\":{\".\":{},\"f:run\":{}}},\"f:spec\":{\"f:containers\":{\"k:{\\\"name\\\":\\\"my-pod\\\"}\":{\".\":{},\"f:image\":{},\"f:imagePullPolicy\":{},\"f:name\":{},\"f:resources\":{},\"f:terminationMessagePath\":{},\"f:terminationMessagePolicy\":{}}},\"f:dnsPolicy\":{},\"f:enableServiceLinks\":{},\"f:restartPolicy\":{},\"f:schedulerName\":{},\"f:securityContext\":{},\"f:terminationGracePeriodSeconds\":{}}}}]},\"spec\":{\"volumes\":[{\"name\":\"kube-api-access-bk2dx\",\"projected\":{\"sources\":[{\"serviceAccountToken\":{\"expirationSeconds\":3607,\"path\":\"token\"}},{\"configMap\":{\"name\":\"kube-root-ca.crt\",\"items\":[{\"key\":\"ca.crt\",\"path\":\"ca.crt\"}]}},{\"downwardAPI\":{\"items\":[{\"pa [truncated 995 chars]" pod/my-pod created |
TG_POD 조회는 disable 시키고 아래 모습으로 새로운 Thread Group을 구성합니다.

HTTP Request 내용은 아래와 같이 설정합니다.
- POST
- path: /api/v1/namespaces/default/pods
- Body Data
|
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "my-pod",
"creationTimestamp": null,
"labels": {
"run": "my-pod"
}
},
"spec": {
"containers": [
{
"name": "my-pod",
"image": "registry.k8s.io/pause:3.9",
"resources": {}
}
],
"restartPolicy": "Always",
"dnsPolicy": "ClusterFirst"
},
"status": {}
}
|

POST 방식으로 JSON 을 전달하기 위해서는 Http Header 에 "Content-Type: application/json"을 추가하여야 합니다.

부하를 발생시키면 default 네임스페이스에 my-pod 가 이미 존재하여 에러가 발생합니다.

이문제를 해결하기 위해 전달되는 JSON의 POD name에 ${__UUID} 추가 합니다.

부하량 조정
"TG_POD 생성" Thread Group 의 설정을 아래와 같이 조정합니다.

10 명의 가상유저가 60초동안 점진적으로 증가시키고 300초 동안 부하를 발생
부하 테스트 시작
- 툴바의 ▶ (start)버튼 클릭하고 각종 리스너의 그래프 및 그라파나 패널 모니터링







| # 현재 default 네임스페이스에 총 2700개의 POD가 생성되어 있습니다. kubectl get po | wc -l 2731 # 이중에 Pending 상태의 POD가 2637 개입니다. kubectl get po --field-selector status.phase=Pending | wc -l 2637 # Pending 상태인 이유를 알아보면 가용한 노드가 없어서입니다. k describe po my-pod-ffde8d75-1a24-4c8e-bae5-4ee15b701749 ...(생략)... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 4m16s default-scheduler 0/1 nodes are available: 1 Too many pods. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod. |
지금까지의 Jmeter 스크립트 파일을 아래에 첨부하였습니다.
3. 추가 연구 목록
이번 블로그에서는 ServiceAccount 를 이용하여 인증을 통과한 후에 부하를 발생하였습니다.
심화학습으로 Kubernetes 클라이언트 인증서를 이용한 인증 후 Jmeter에서 부하를 발생하는 방법에 대해 알아봐야 할 거 같습니다.
4. 다른 부하 도구들
Apache Jmeter는 범용적인 부하테스트 도구입니다.
아래는 Kubernetes에 특화된 부하테스트 도구 정보입니다.
- Kube-burner
- Kubernetes perf-tests
'Kubernetes' 카테고리의 다른 글
| MinIO 소개 (0) | 2025.09.13 |
|---|---|
| Cilium Study [1기] (8주차) - Cilium Security (0) | 2025.09.04 |
| Cilium Study [1기] (6주차) - Cilium ServiceMesh (0) | 2025.08.19 |
| Cilium Study [1기] (5주차) - BGP Control Plane (4) | 2025.08.13 |
| Cilium Study [1기] (4주차) - Networking - 노드에 파드들간 통신 2 & K8S 외부 노출 (0) | 2025.08.07 |








