Merge pull request #33781 from jihoon-seo/220516_ko_Reorg_the_Debugging_section
[ko] Reorg pages in `dev-1.24-ko.1`
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
---
|
||||
|
||||
|
||||
title: 클러스터 트러블슈팅
|
||||
description: 일반적인 클러스터 이슈를 디버깅한다.
|
||||
weight: 20
|
||||
no_list: true
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
이 문서는 클러스터 트러블슈팅에 대해 설명한다. 사용자가 겪고 있는 문제의 근본 원인으로서 사용자의 애플리케이션을
|
||||
이미 배제했다고 가정한다.
|
||||
애플리케이션 디버깅에 대한 팁은 [애플리케이션 트러블슈팅 가이드](/ko/docs/tasks/debug/debug-application/)를 참조한다.
|
||||
자세한 내용은 [트러블슈팅 문서](/ko/docs/tasks/debug/)를 참조한다.
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## 클러스터 나열하기
|
||||
|
||||
클러스터에서 가장 먼저 디버그해야 할 것은 노드가 모두 올바르게 등록되었는지 여부이다.
|
||||
|
||||
다음을 실행한다.
|
||||
|
||||
```shell
|
||||
kubectl get nodes
|
||||
```
|
||||
|
||||
그리고 보일 것으로 예상되는 모든 노드가 존재하고 모두 `Ready` 상태인지 확인한다.
|
||||
|
||||
클러스터의 전반적인 상태에 대한 자세한 정보를 얻으려면 다음을 실행할 수 있다.
|
||||
|
||||
```shell
|
||||
kubectl cluster-info dump
|
||||
```
|
||||
|
||||
### 예제: 다운(down) 상태이거나 통신이 닿지 않는(unreachable) 노드 디버깅하기
|
||||
|
||||
때때로 디버깅할 때 노드의 상태를 확인하는 것이 유용할 수 있다(예를 들어, 어떤 노드에서 실행되는 파드가 이상하게 행동하는 것을 발견했거나, 특정 노드에 파드가 스케줄링되지 않는 이유를 알아보기 위해). 파드의 경우와 마찬가지로, `kubectl describe node` 및 `kubectl get node -o yaml` 명령을 사용하여 노드에 대한 상세 정보를 볼 수 있다. 예를 들어, 노드가 다운 상태(네트워크 연결이 끊어졌거나, kubelet이 종료된 후 재시작되지 못했거나 등)라면 아래와 같은 출력이 나올 것이다. 노드가 NotReady 상태라는 것을 나타내는 이벤트(event)와, 더 이상 실행 중이 아닌 파드(NotReady 상태 이후 5분 뒤에 축출되었음)에 주목한다.
|
||||
|
||||
```shell
|
||||
kubectl get nodes
|
||||
```
|
||||
|
||||
```none
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
kube-worker-1 NotReady <none> 1h v1.23.3
|
||||
kubernetes-node-bols Ready <none> 1h v1.23.3
|
||||
kubernetes-node-st6x Ready <none> 1h v1.23.3
|
||||
kubernetes-node-unaj Ready <none> 1h v1.23.3
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl describe node kube-worker-1
|
||||
```
|
||||
|
||||
```none
|
||||
Name: kube-worker-1
|
||||
Roles: <none>
|
||||
Labels: beta.kubernetes.io/arch=amd64
|
||||
beta.kubernetes.io/os=linux
|
||||
kubernetes.io/arch=amd64
|
||||
kubernetes.io/hostname=kube-worker-1
|
||||
kubernetes.io/os=linux
|
||||
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /run/containerd/containerd.sock
|
||||
node.alpha.kubernetes.io/ttl: 0
|
||||
volumes.kubernetes.io/controller-managed-attach-detach: true
|
||||
CreationTimestamp: Thu, 17 Feb 2022 16:46:30 -0500
|
||||
Taints: node.kubernetes.io/unreachable:NoExecute
|
||||
node.kubernetes.io/unreachable:NoSchedule
|
||||
Unschedulable: false
|
||||
Lease:
|
||||
HolderIdentity: kube-worker-1
|
||||
AcquireTime: <unset>
|
||||
RenewTime: Thu, 17 Feb 2022 17:13:09 -0500
|
||||
Conditions:
|
||||
Type Status LastHeartbeatTime LastTransitionTime Reason Message
|
||||
---- ------ ----------------- ------------------ ------ -------
|
||||
NetworkUnavailable False Thu, 17 Feb 2022 17:09:13 -0500 Thu, 17 Feb 2022 17:09:13 -0500 WeaveIsUp Weave pod has set this
|
||||
MemoryPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
|
||||
DiskPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
|
||||
PIDPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
|
||||
Ready Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
|
||||
Addresses:
|
||||
InternalIP: 192.168.0.113
|
||||
Hostname: kube-worker-1
|
||||
Capacity:
|
||||
cpu: 2
|
||||
ephemeral-storage: 15372232Ki
|
||||
hugepages-2Mi: 0
|
||||
memory: 2025188Ki
|
||||
pods: 110
|
||||
Allocatable:
|
||||
cpu: 2
|
||||
ephemeral-storage: 14167048988
|
||||
hugepages-2Mi: 0
|
||||
memory: 1922788Ki
|
||||
pods: 110
|
||||
System Info:
|
||||
Machine ID: 9384e2927f544209b5d7b67474bbf92b
|
||||
System UUID: aa829ca9-73d7-064d-9019-df07404ad448
|
||||
Boot ID: 5a295a03-aaca-4340-af20-1327fa5dab5c
|
||||
Kernel Version: 5.13.0-28-generic
|
||||
OS Image: Ubuntu 21.10
|
||||
Operating System: linux
|
||||
Architecture: amd64
|
||||
Container Runtime Version: containerd://1.5.9
|
||||
Kubelet Version: v1.23.3
|
||||
Kube-Proxy Version: v1.23.3
|
||||
Non-terminated Pods: (4 in total)
|
||||
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
|
||||
--------- ---- ------------ ---------- --------------- ------------- ---
|
||||
default nginx-deployment-67d4bdd6f5-cx2nz 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
|
||||
default nginx-deployment-67d4bdd6f5-w6kd7 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
|
||||
kube-system kube-proxy-dnxbz 0 (0%) 0 (0%) 0 (0%) 0 (0%) 28m
|
||||
kube-system weave-net-gjxxp 100m (5%) 0 (0%) 200Mi (10%) 0 (0%) 28m
|
||||
Allocated resources:
|
||||
(Total limits may be over 100 percent, i.e., overcommitted.)
|
||||
Resource Requests Limits
|
||||
-------- -------- ------
|
||||
cpu 1100m (55%) 1 (50%)
|
||||
memory 456Mi (24%) 256Mi (13%)
|
||||
ephemeral-storage 0 (0%) 0 (0%)
|
||||
hugepages-2Mi 0 (0%) 0 (0%)
|
||||
Events:
|
||||
...
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl get node kube-worker-1 -o yaml
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Node
|
||||
metadata:
|
||||
annotations:
|
||||
kubeadm.alpha.kubernetes.io/cri-socket: /run/containerd/containerd.sock
|
||||
node.alpha.kubernetes.io/ttl: "0"
|
||||
volumes.kubernetes.io/controller-managed-attach-detach: "true"
|
||||
creationTimestamp: "2022-02-17T21:46:30Z"
|
||||
labels:
|
||||
beta.kubernetes.io/arch: amd64
|
||||
beta.kubernetes.io/os: linux
|
||||
kubernetes.io/arch: amd64
|
||||
kubernetes.io/hostname: kube-worker-1
|
||||
kubernetes.io/os: linux
|
||||
name: kube-worker-1
|
||||
resourceVersion: "4026"
|
||||
uid: 98efe7cb-2978-4a0b-842a-1a7bf12c05f8
|
||||
spec: {}
|
||||
status:
|
||||
addresses:
|
||||
- address: 192.168.0.113
|
||||
type: InternalIP
|
||||
- address: kube-worker-1
|
||||
type: Hostname
|
||||
allocatable:
|
||||
cpu: "2"
|
||||
ephemeral-storage: "14167048988"
|
||||
hugepages-2Mi: "0"
|
||||
memory: 1922788Ki
|
||||
pods: "110"
|
||||
capacity:
|
||||
cpu: "2"
|
||||
ephemeral-storage: 15372232Ki
|
||||
hugepages-2Mi: "0"
|
||||
memory: 2025188Ki
|
||||
pods: "110"
|
||||
conditions:
|
||||
- lastHeartbeatTime: "2022-02-17T22:20:32Z"
|
||||
lastTransitionTime: "2022-02-17T22:20:32Z"
|
||||
message: Weave pod has set this
|
||||
reason: WeaveIsUp
|
||||
status: "False"
|
||||
type: NetworkUnavailable
|
||||
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
|
||||
lastTransitionTime: "2022-02-17T22:13:25Z"
|
||||
message: kubelet has sufficient memory available
|
||||
reason: KubeletHasSufficientMemory
|
||||
status: "False"
|
||||
type: MemoryPressure
|
||||
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
|
||||
lastTransitionTime: "2022-02-17T22:13:25Z"
|
||||
message: kubelet has no disk pressure
|
||||
reason: KubeletHasNoDiskPressure
|
||||
status: "False"
|
||||
type: DiskPressure
|
||||
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
|
||||
lastTransitionTime: "2022-02-17T22:13:25Z"
|
||||
message: kubelet has sufficient PID available
|
||||
reason: KubeletHasSufficientPID
|
||||
status: "False"
|
||||
type: PIDPressure
|
||||
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
|
||||
lastTransitionTime: "2022-02-17T22:15:15Z"
|
||||
message: kubelet is posting ready status. AppArmor enabled
|
||||
reason: KubeletReady
|
||||
status: "True"
|
||||
type: Ready
|
||||
daemonEndpoints:
|
||||
kubeletEndpoint:
|
||||
Port: 10250
|
||||
nodeInfo:
|
||||
architecture: amd64
|
||||
bootID: 22333234-7a6b-44d4-9ce1-67e31dc7e369
|
||||
containerRuntimeVersion: containerd://1.5.9
|
||||
kernelVersion: 5.13.0-28-generic
|
||||
kubeProxyVersion: v1.23.3
|
||||
kubeletVersion: v1.23.3
|
||||
machineID: 9384e2927f544209b5d7b67474bbf92b
|
||||
operatingSystem: linux
|
||||
osImage: Ubuntu 21.10
|
||||
systemUUID: aa829ca9-73d7-064d-9019-df07404ad448
|
||||
```
|
||||
|
||||
|
||||
## 로그 보기
|
||||
|
||||
현재로서는 클러스터를 더 깊이 파고들려면 관련 머신에서 로그 확인이 필요하다. 관련 로그 파일
|
||||
위치는 다음과 같다. (systemd 기반 시스템에서는 `journalctl`을 대신 사용해야 할 수도 있다.)
|
||||
|
||||
### 컨트롤 플레인 노드
|
||||
|
||||
* `/var/log/kube-apiserver.log` - API 서버, API 제공을 담당
|
||||
* `/var/log/kube-scheduler.log` - 스케줄러, 스케줄 결정을 담당
|
||||
* `/var/log/kube-controller-manager.log` - 레플리케이션 컨트롤러를 담당하는 컨트롤러
|
||||
|
||||
### 워커 노드
|
||||
|
||||
* `/var/log/kubelet.log` - Kubelet, 노드에서 컨테이너 실행을 담당
|
||||
* `/var/log/kube-proxy.log` - Kube Proxy, 서비스 로드밸런싱을 담당
|
||||
|
||||
## 클러스터 장애 모드
|
||||
|
||||
아래에 일부 오류 상황 예시 및 문제를 완화하기 위해 클러스터 설정을 조정하는 방법을 나열한다.
|
||||
|
||||
### 근본 원인
|
||||
|
||||
- VM(들) 종료
|
||||
- 클러스터 내 또는 클러스터와 사용자 간의 네트워크 분할
|
||||
- 쿠버네티스 소프트웨어의 충돌
|
||||
- 데이터 손실 또는 퍼시스턴트 스토리지 사용 불가 (e.g. GCE PD 또는 AWS EBS 볼륨)
|
||||
- 운영자 오류, 예를 들면 잘못 구성된 쿠버네티스 소프트웨어 또는 애플리케이션 소프트웨어
|
||||
|
||||
### 특정 시나리오
|
||||
|
||||
- API 서버 VM 종료 또는 API 서버 충돌
|
||||
- 다음의 현상을 유발함
|
||||
- 새로운 파드, 서비스, 레플리케이션 컨트롤러를 중지, 업데이트 또는 시작할 수 없다.
|
||||
- 쿠버네티스 API에 의존하지 않는 기존 파드 및 서비스는 계속 정상적으로 작동할 것이다.
|
||||
- API 서버 백업 스토리지 손실
|
||||
- 다음의 현상을 유발함
|
||||
- API 서버가 구동되지 않을 것이다.
|
||||
- kubelet에 도달할 수 없게 되지만, kubelet이 여전히 동일한 파드를 계속 실행하고 동일한 서비스 프록시를 제공할 것이다.
|
||||
- API 서버를 재시작하기 전에, 수동으로 복구하거나 API서버 상태를 재생성해야 한다.
|
||||
- 지원 서비스 (노드 컨트롤러, 레플리케이션 컨트롤러 매니저, 스케쥴러 등) VM 종료 또는 충돌
|
||||
- 현재 그것들은 API 서버와 같은 위치에 있기 때문에 API 서버와 비슷한 상황을 겪을 것이다.
|
||||
- 미래에는 이들도 복제본을 가질 것이며 API서버와 별도로 배치될 수도 있다.
|
||||
- 지원 서비스들은 상태(persistent state)를 자체적으로 유지하지는 않는다.
|
||||
- 개별 노드 (VM 또는 물리적 머신) 종료
|
||||
- 다음의 현상을 유발함
|
||||
- 해당 노드의 파드가 실행을 중지
|
||||
- 네트워크 분할
|
||||
- 다음의 현상을 유발함
|
||||
- 파티션 A는 파티션 B의 노드가 다운되었다고 생각한다. 파티션 B는 API 서버가 다운되었다고 생각한다. (마스터 VM이 파티션 A에 있다고 가정)
|
||||
- Kubelet 소프트웨어 오류
|
||||
- 다음의 현상을 유발함
|
||||
- 충돌한 kubelet은 노드에서 새 파드를 시작할 수 없다.
|
||||
- kubelet이 파드를 삭제할 수도 있고 삭제하지 않을 수도 있다.
|
||||
- 노드는 비정상으로 표시된다.
|
||||
- 레플리케이션 컨트롤러는 다른 곳에서 새 파드를 시작한다.
|
||||
- 클러스터 운영자 오류
|
||||
- 다음의 현상을 유발함
|
||||
- 파드, 서비스 등의 손실
|
||||
- API 서버 백업 저장소 분실
|
||||
- API를 읽을 수 없는 사용자
|
||||
- 기타
|
||||
|
||||
### 완화
|
||||
|
||||
- 조치: IaaS VM을 위한 IaaS 공급자의 자동 VM 다시 시작 기능을 사용한다.
|
||||
- 다음을 완화할 수 있음: API 서버 VM 종료 또는 API 서버 충돌
|
||||
- 다음을 완화할 수 있음: 지원 서비스 VM 종료 또는 충돌
|
||||
|
||||
- 조치: API 서버+etcd가 있는 VM에 IaaS 제공자의 안정적인 스토리지(예: GCE PD 또는 AWS EBS 볼륨)를 사용한다.
|
||||
- 다음을 완화할 수 있음: API 서버 백업 스토리지 손실
|
||||
|
||||
- 조치: [고가용성](/docs/setup/production-environment/tools/kubeadm/high-availability/) 구성을 사용한다.
|
||||
- 다음을 완화할 수 있음: 컨트롤 플레인 노드 종료 또는 컨트롤 플레인 구성 요소(스케줄러, API 서버, 컨트롤러 매니저) 충돌
|
||||
- 동시에 발생하는 하나 이상의 노드 또는 구성 요소 오류를 허용한다.
|
||||
- 다음을 완화할 수 있음: API 서버 백업 스토리지(i.e., etcd의 데이터 디렉터리) 손실
|
||||
- 고가용성 etcd 구성을 사용하고 있다고 가정
|
||||
|
||||
- 조치: API 서버 PD/EBS 볼륨의 주기적인 스냅샷
|
||||
- 다음을 완화할 수 있음: API 서버 백업 스토리지 손실
|
||||
- 다음을 완화할 수 있음: 일부 운영자 오류 사례
|
||||
- 다음을 완화할 수 있음: 일부 쿠버네티스 소프트웨어 오류 사례
|
||||
|
||||
- 조치: 파드 앞에 레플리케이션 컨트롤러와 서비스 사용
|
||||
- 다음을 완화할 수 있음: 노드 종료
|
||||
- 다음을 완화할 수 있음: Kubelet 소프트웨어 오류
|
||||
|
||||
- 조치: 예기치 않은 재시작을 허용하도록 설계된 애플리케이션(컨테이너)
|
||||
- 다음을 완화할 수 있음: 노드 종료
|
||||
- 다음을 완화할 수 있음: Kubelet 소프트웨어 오류
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* [리소스 메트릭 파이프라인](/ko/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/)에서 사용할 수 있는 메트릭에 대해 알아 본다.
|
||||
* [리소스 사용량 모니터링](/ko/docs/tasks/debug/debug-cluster/resource-usage-monitoring/)을 위한 추가 도구에 대해 알아 본다.
|
||||
* Node Problem Detector를 사용하여 [노드 헬스(health)를 모니터링](/docs/tasks/debug/debug-cluster/monitor-node-health/)한다.
|
||||
* `crictl`을 사용하여 [쿠버네티스 노드를 디버깅](/docs/tasks/debug/debug-cluster/crictl/)한다.
|
||||
* [쿠버네티스 감사(auditing)](/docs/tasks/debug/debug-cluster/audit/)에 대한 더 자세한 정보를 본다.
|
||||
* `telepresence`를 사용하여 [서비스를 로컬에서 개발 및 디버깅](/docs/tasks/debug/debug-cluster/local-debugging/)한다.
|
||||
@@ -0,0 +1,268 @@
|
||||
---
|
||||
|
||||
|
||||
|
||||
title: 리소스 메트릭 파이프라인
|
||||
content_type: concept
|
||||
weight: 15
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
쿠버네티스에서, _메트릭 API(Metrics API)_ 는 자동 스케일링 및 비슷한 사용 사례를 지원하기 위한 기본적인 메트릭 집합을 제공한다.
|
||||
이 API는 노드와 파드의 리소스 사용량 정보를 제공하며,
|
||||
여기에는 CPU 및 메모리 메트릭이 포함된다.
|
||||
메트릭 API를 클러스터에 배포하면, 쿠버네티스 API의 클라이언트는 이 정보에 대해 질의할 수 있으며,
|
||||
질의 권한을 관리하기 위해 쿠버네티스의 접근 제어 메커니즘을 이용할 수 있다.
|
||||
|
||||
[HorizontalPodAutoscaler](/ko/docs/tasks/run-application/horizontal-pod-autoscale/)(HPA) 및
|
||||
[VerticalPodAutoscaler](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#readme)(VPA)는
|
||||
사용자의 요구 사항을 만족할 수 있도록 워크로드 레플리카와 리소스를 조정하는 데에 메트릭 API의 데이터를 이용한다.
|
||||
|
||||
[`kubectl top`](/docs/reference/generated/kubectl/kubectl-commands#top)
|
||||
명령을 이용하여
|
||||
리소스 메트릭을 볼 수도 있다.
|
||||
|
||||
{{< note >}}
|
||||
메트릭 API 및 이것이 제공하는 메트릭 파이프라인은
|
||||
HPA / VPA 에 의한 자동 스케일링이 동작하는 데 필요한
|
||||
최소한의 CPU 및 메모리 메트릭만을 제공한다.
|
||||
더 많은 메트릭 집합을 제공하려면, _커스텀 메트릭 API_ 를 사용하는
|
||||
추가 [메트릭 파이프라인](/ko/docs/tasks/debug/debug-cluster/resource-usage-monitoring/#full-metrics-pipeline)을 배포하여
|
||||
기본 메트릭 API를 보충할 수 있다.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
그림 1은 리소스 메트릭 파이프라인의 아키텍처를 나타낸다.
|
||||
|
||||
{{< mermaid >}}
|
||||
flowchart RL
|
||||
subgraph cluster[클러스터]
|
||||
direction RL
|
||||
S[ <br><br> ]
|
||||
A[Metrics-<br>Server]
|
||||
subgraph B[노드]
|
||||
direction TB
|
||||
D[cAdvisor] --> C[kubelet]
|
||||
E[컨테이너<br>런타임] --> D
|
||||
E1[컨테이너<br>런타임] --> D
|
||||
P[파드 데이터] -.- C
|
||||
end
|
||||
L[API<br>서버]
|
||||
W[HPA]
|
||||
C ---->|요약<br>API| A -->|메트릭<br>API| L --> W
|
||||
end
|
||||
L ---> K[kubectl<br>top]
|
||||
classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000;
|
||||
class W,B,P,K,cluster,D,E,E1 box
|
||||
classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000
|
||||
class S spacewhite
|
||||
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff;
|
||||
class A,L,C k8s
|
||||
{{< /mermaid >}}
|
||||
|
||||
그림 1. 리소스 메트릭 파이프라인
|
||||
|
||||
그림의 오른쪽에서 왼쪽 순으로, 아키텍처 구성 요소는 다음과 같다.
|
||||
|
||||
* [cAdvisor](https://github.com/google/cadvisor): kubelet에 포함된 컨테이너 메트릭을
|
||||
수집, 집계, 노출하는 데몬
|
||||
* [kubelet](/ko/docs/concepts/overview/components/#kubelet): 컨테이너 리소스 관리를 위한 노드 에이전트.
|
||||
리소스 메트릭은 kubelet API 엔드포인트 `/metrics/resource` 및
|
||||
`/stats` 를 사용하여 접근 가능하다.
|
||||
* [요약 API](#summary-api-source): `/stats` 엔드포인트를 통해 사용할 수 있는
|
||||
노드 별 요약된 정보를 탐색 및 수집할 수 있도록 kubelet이 제공하는 API
|
||||
* [metrics-server](#metrics-server): 각 kubelet으로부터 수집한 리소스 메트릭을 수집 및 집계하는 클러스터 애드온 구성 요소.
|
||||
API 서버는 HPA, VPA 및 `kubectl top` 명령어가 사용할 수 있도록 메트릭 API를 제공한다.
|
||||
metrics-server는 메트릭 API에 대한 기준 구현(reference implementation) 중 하나이다.
|
||||
* [메트릭 API](#metrics-api): 워크로드 오토스케일링에 사용되는 CPU 및 메모리 정보로의 접근을 지원하는 쿠버네티스 API.
|
||||
이를 클러스터에서 사용하려면,
|
||||
메트릭 API를 제공하는 API 확장(extension) 서버가 필요하다.
|
||||
|
||||
{{< note >}}
|
||||
cAdvisor는 cgroups으로부터 메트릭을 가져오는 것을 지원하며, 리눅스의 일반적인 컨테이너 런타임은 이를 지원한다.
|
||||
만약 다른 리소스 격리 메커니즘(예: 가상화)을 사용하는 컨테이너 런타임을 사용한다면,
|
||||
kubelet이 메트릭을 사용할 수 있기 위해서는
|
||||
해당 컨테이너 런타임이
|
||||
[CRI 컨테이너 메트릭](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-container-stats.md)을 지원해야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## 메트릭 API {#metrics-api}
|
||||
{{< feature-state for_k8s_version="1.8" state="beta" >}}
|
||||
|
||||
metrics-server는 메트릭 API에 대한 구현이다.
|
||||
이 API는 클러스터 내 노드와 파드의 CPU 및 메모리 사용 정보에 접근할 수 있게 해 준다.
|
||||
이것의 주 역할은 리소스 사용 메트릭을 쿠버네티스 오토스케일러 구성 요소에 제공하는 것이다.
|
||||
|
||||
다음은 `minikube` 노드에 대한 메트릭 API 요청 예시이며
|
||||
가독성 향상을 위해 `jq`를 활용한다.
|
||||
|
||||
```shell
|
||||
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes/minikube" | jq '.'
|
||||
```
|
||||
|
||||
다음은 `curl`을 이용하여 동일한 API 호출을 하는 명령어다.
|
||||
|
||||
```shell
|
||||
curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/nodes/minikube
|
||||
```
|
||||
|
||||
응답 예시는 다음과 같다.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "NodeMetrics",
|
||||
"apiVersion": "metrics.k8s.io/v1beta1",
|
||||
"metadata": {
|
||||
"name": "minikube",
|
||||
"selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/minikube",
|
||||
"creationTimestamp": "2022-01-27T18:48:43Z"
|
||||
},
|
||||
"timestamp": "2022-01-27T18:48:33Z",
|
||||
"window": "30s",
|
||||
"usage": {
|
||||
"cpu": "487558164n",
|
||||
"memory": "732212Ki"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
다음은 `kube-system` 네임스페이스 내의 `kube-scheduler-minikube` 파드에 대한
|
||||
메트릭 API 요청 예시이며 가독성 향상을 위해 `jq`를 활용한다.
|
||||
|
||||
```shell
|
||||
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube" | jq '.'
|
||||
```
|
||||
|
||||
다음은 `curl`을 이용하여 동일한 API 호출을 하는 명령어다.
|
||||
|
||||
```shell
|
||||
curl http://localhost:8080/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube
|
||||
```
|
||||
|
||||
응답 예시는 다음과 같다.
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "PodMetrics",
|
||||
"apiVersion": "metrics.k8s.io/v1beta1",
|
||||
"metadata": {
|
||||
"name": "kube-scheduler-minikube",
|
||||
"namespace": "kube-system",
|
||||
"selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/kube-system/pods/kube-scheduler-minikube",
|
||||
"creationTimestamp": "2022-01-27T19:25:00Z"
|
||||
},
|
||||
"timestamp": "2022-01-27T19:24:31Z",
|
||||
"window": "30s",
|
||||
"containers": [
|
||||
{
|
||||
"name": "kube-scheduler",
|
||||
"usage": {
|
||||
"cpu": "9559630n",
|
||||
"memory": "22244Ki"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
메트릭 API는 [k8s.io/metrics](https://github.com/kubernetes/metrics) 저장소에 정의되어 있다.
|
||||
`metrics.k8s.io` API를 사용하기 위해서는
|
||||
[API 집계(aggregation) 계층](/docs/tasks/extend-kubernetes/configure-aggregation-layer/)을 활성화하고
|
||||
[APIService](/docs/reference/kubernetes-api/cluster-resources/api-service-v1/)를 등록해야 한다.
|
||||
|
||||
메트릭 API에 대해 더 알아보려면, [리소스 메트릭 API 디자인](https://github.com/kubernetes/design-proposals-archive/blob/main/instrumentation/resource-metrics-api.md),
|
||||
[metrics-server 저장소](https://github.com/kubernetes-sigs/metrics-server) 및
|
||||
[리소스 메트릭 API](https://github.com/kubernetes/metrics#resource-metrics-api)를 참고한다.
|
||||
|
||||
|
||||
{{< note >}}
|
||||
메트릭 API에 접근하려면 먼저 메트릭 API를 제공하는
|
||||
metrics-server 또는 대체 어댑터를 배포해야 한다.
|
||||
{{< /note >}}
|
||||
|
||||
## 리소스 사용량 측정 {#measuring-resource-usage}
|
||||
|
||||
### CPU
|
||||
|
||||
CPU는 `cpu` 단위로 측정된 평균 코어 사용량 형태로 보고된다. 쿠버네티스에서 1 cpu는
|
||||
클라우드 제공자의 경우 1 vCPU/코어에 해당하고, 베어메탈 인텔 프로세서의 경우 1 하이퍼-스레드에 해당한다.
|
||||
|
||||
이 값은 커널(Linux 및 Windows 커널 모두)에서 제공하는 누적 CPU 카운터에 대한
|
||||
비율을 취하여 얻어진다.
|
||||
CPU 값 계산에 사용된 타임 윈도우는 메트릭 API의 `window` 필드에 표시된다.
|
||||
|
||||
쿠버네티스가 어떻게 CPU 리소스를 할당하고 측정하는지 더 알아보려면,
|
||||
[CPU의 의미](/ko/docs/concepts/configuration/manage-resources-containers/#meaning-of-cpu)를 참고한다.
|
||||
|
||||
### 메모리
|
||||
|
||||
메모리는 메트릭을 수집하는 순간에 바이트 단위로 측정된 워킹 셋(working set) 형태로 보고된다.
|
||||
|
||||
이상적인 환경에서, "워킹 셋"은 메모리가 부족한 상태더라도 해제할 수 없는 사용 중인 메모리의 양이다.
|
||||
그러나 워킹 셋의 계산 방법은 호스트 OS에 따라 다르며
|
||||
일반적으로 추정치를 추출하기 위해 휴리스틱을 많이 사용한다.
|
||||
|
||||
컨테이너의 워킹 셋에 대한 쿠버네티스 모델은 컨테이너 런타임이 해당 컨테이너와 연결된 익명(anonymous) 메모리를 계산할 것으로 예상한다.
|
||||
호스트 OS가 항상 페이지를 회수할 수는 없기 때문에,
|
||||
워킹 셋 메트릭에는 일반적으로 일부 캐시된 (파일 기반) 메모리도 포함된다.
|
||||
|
||||
쿠버네티스가 어떻게 메모리 리소스를 할당하고 측정하는지 더 알아보려면,
|
||||
[메모리의 의미](/ko/docs/concepts/configuration/manage-resources-containers/#meaning-of-memory)를 참고한다.
|
||||
|
||||
## metrics-server {#metrics-server}
|
||||
|
||||
metrics-server는 kubelet으로부터 리소스 메트릭을 수집하고,
|
||||
이를 HPA(Horizontal Pod Autoscaler) 및 VPA(Vertical Pod Autoscaler)가 활용할 수 있도록 쿠버네티스 API 서버 내에서 메트릭 API(Metrics API)를 통해 노출한다.
|
||||
`kubectl top` 명령을 사용하여 이 메트릭을 확인해볼 수도 있다.
|
||||
|
||||
metrics-server는 쿠버네티스 API를 사용하여 클러스터의 노드와 파드를 추적한다.
|
||||
metrics-server는 각 노드에 HTTP를 통해 질의하여 메트릭을 수집한다.
|
||||
metrics-server는 또한 파드 메타데이터의 내부적 뷰를 작성하고, 파드 헬스(health)에 대한 캐시를 유지한다.
|
||||
이렇게 캐시된 파드 헬스 정보는 metrics-server가 제공하는 확장 API(extension API)를 통해 이용할 수 있다.
|
||||
|
||||
HPA 질의에 대한 예시에서, 예를 들어 HPA 질의에 대한 경우,
|
||||
metrics-server는 디플로이먼트의 어떤 파드가 레이블 셀렉터 조건을 만족하는지 판별해야 한다.
|
||||
|
||||
metrics-server는 각 노드로부터 메트릭을 수집하기 위해 [kubelet](/docs/reference/command-line-tools-reference/kubelet/) API를 호출한다.
|
||||
사용 중인 metrics-server 버전에 따라, 다음의 엔드포인트를 사용한다.
|
||||
|
||||
* v0.6.0 이상: 메트릭 리소스 엔드포인트 `/metrics/resource`
|
||||
* 이전 버전: 요약 API 엔드포인트 `/stats/summary`
|
||||
|
||||
metrics-server에 대한 더 많은 정보는
|
||||
[metrics-server 저장소](https://github.com/kubernetes-sigs/metrics-server)를 확인한다.
|
||||
|
||||
또한 다음을 참고할 수도 있다.
|
||||
|
||||
* [metrics-server 디자인](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/metrics-server.md)
|
||||
* [metrics-server 자주 묻는 질문](https://github.com/kubernetes-sigs/metrics-server/blob/master/FAQ.md)
|
||||
* [metrics-server 알려진 이슈](https://github.com/kubernetes-sigs/metrics-server/blob/master/KNOWN_ISSUES.md)
|
||||
* [metrics-server 릴리스](https://github.com/kubernetes-sigs/metrics-server/releases)
|
||||
* [Horizontal Pod Autoscaling](/ko/docs/tasks/run-application/horizontal-pod-autoscale/)
|
||||
|
||||
### 요약 API(Summary API) 소스 {#summary-api-source}
|
||||
|
||||
[Kubelet](/docs/reference/command-line-tools-reference/kubelet/)은
|
||||
노드, 볼륨, 파드, 컨테이너 수준의 통계를 수집하며,
|
||||
소비자(consumer)가 읽을 수 있도록 이 통계를
|
||||
[요약 API](https://github.com/kubernetes/kubernetes/blob/7d309e0104fedb57280b261e5677d919cb2a0e2d/staging/src/k8s.io/kubelet/pkg/apis/stats/v1alpha1/types.go)에 기록한다.
|
||||
|
||||
다음은 `minikube` 노드에 대한 요약 API 요청 예시이다.
|
||||
|
||||
```shell
|
||||
kubectl get --raw "/api/v1/nodes/minikube/proxy/stats/summary"
|
||||
```
|
||||
|
||||
다음은 `curl`을 이용하여 동일한 API 호출을 하는 명령어다.
|
||||
|
||||
```shell
|
||||
curl http://localhost:8080/api/v1/nodes/minikube/proxy/stats/summary
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
metrics-server 0.6.x 버전부터,
|
||||
요약 API `/stats/summary` 엔드포인트가 `/metrics/resource` 엔드포인트로 대체될 것이다.
|
||||
{{< /note >}}
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
|
||||
|
||||
content_type: concept
|
||||
title: 리소스 모니터링 도구
|
||||
weight: 15
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
애플리케이션을 스케일하여 신뢰할 수 있는 서비스를 제공하려면,
|
||||
애플리케이션이 배포되었을 때 애플리케이션이 어떻게 동작하는지를 이해해야 한다.
|
||||
컨테이너, [파드](/ko/docs/concepts/workloads/pods/),
|
||||
[서비스](/ko/docs/concepts/services-networking/service),
|
||||
그리고 전체 클러스터의 특성을 검사하여
|
||||
쿠버네티스 클러스터 내의 애플리케이션 성능을 검사할 수 있다. 쿠버네티스는 각 레벨에서
|
||||
애플리케이션의 리소스 사용량에 대한 상세 정보를 제공한다.
|
||||
이 정보는 애플리케이션의 성능을 평가하고
|
||||
병목 현상을 제거하여 전체 성능을 향상할 수 있게 해준다.
|
||||
|
||||
<!-- body -->
|
||||
|
||||
쿠버네티스에서 애플리케이션 모니터링은 단일 모니터링 솔루션에 의존하지 않는다.
|
||||
신규 클러스터에서는, [리소스 메트릭](#리소스-메트릭-파이프라인) 또는
|
||||
[완전한 메트릭](#완전한-메트릭-파이프라인) 파이프라인으로 모니터링 통계를 수집할 수 있다.
|
||||
|
||||
## 리소스 메트릭 파이프라인
|
||||
|
||||
리소스 메트릭 파이프라인은
|
||||
[Horizontal Pod Autoscaler](/ko/docs/tasks/run-application/horizontal-pod-autoscale)
|
||||
컨트롤러와 같은 클러스터 구성요소나
|
||||
`kubectl top` 유틸리티에 관련되어 있는
|
||||
메트릭들로 제한된 집합을 제공한다. 이 메트릭은 경량의 단기 인메모리 저장소인
|
||||
[metrics-server](https://github.com/kubernetes-sigs/metrics-server)에
|
||||
의해서 수집되며 `metrics.k8s.io` API를 통해 노출된다.
|
||||
|
||||
metrics-server는 클러스터 상의 모든 노드를 발견하고
|
||||
각 노드의 [kubelet](/docs/reference/command-line-tools-reference/kubelet/)에
|
||||
CPU와 메모리 사용량을 질의한다.
|
||||
Kubelet은 쿠버네티스 마스터와 노드 간의 다리 역할을 하면서
|
||||
머신에서 구동되는 파드와 컨테이너를 관리한다.
|
||||
Kubelet은 각각의 파드를 해당하는 컨테이너에 매치시키고
|
||||
컨테이너 런타임 인터페이스를 통해
|
||||
컨테이너 런타임에서 개별 컨테이너의 사용량 통계를 가져온다.
|
||||
Kubelet은 이 정보를 레거시 도커와의 통합을 위해 kubelet에 통합된 cAdvisor를 통해 가져온다.
|
||||
그 다음으로 취합된 파드 리소스 사용량 통계를 metric-server 리소스 메트릭 API를 통해 노출한다.
|
||||
이 API는 kubelet의 인증이 필요한 읽기 전용 포트 상의
|
||||
`/metrics/resource/v1beta1`에서 제공된다.
|
||||
|
||||
## 완전한 메트릭 파이프라인
|
||||
|
||||
완전한 메트릭 파이프라인은 보다 풍부한 메트릭에 접근할 수 있도록 해준다.
|
||||
쿠버네티스는 Horizontal Pod Autoscaler와 같은 메커니즘을 활용해서 이런 메트릭에
|
||||
대한 반응으로 클러스터의 현재 상태를 기반으로 자동으로 스케일링하거나 클러스터를
|
||||
조정할 수 있다. 모니터링 파이프라인은 kubelet에서 메트릭을 가져와서 쿠버네티스에
|
||||
`custom.metrics.k8s.io`와 `external.metrics.k8s.io` API를 구현한 어댑터를 통해
|
||||
노출한다.
|
||||
|
||||
CNCF 프로젝트인 [프로메테우스](https://prometheus.io)는 기본적으로 쿠버네티스, 노드, 프로메테우스 자체를 모니터링할 수 있다.
|
||||
CNCF 프로젝트가 아닌 완전한 메트릭 파이프라인 프로젝트는 쿠버네티스 문서의 범위가 아니다.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
다음과 같은 추가 디버깅 도구에 대해 더 알아본다.
|
||||
|
||||
* [로깅](/ko/docs/concepts/cluster-administration/logging/)
|
||||
* [모니터링](/ko/docs/tasks/debug/debug-cluster/resource-usage-monitoring/)
|
||||
* [`exec`를 통해 컨테이너에 접속하기](/ko/docs/tasks/debug/debug-application/get-shell-running-container/)
|
||||
* [프록시를 통해 컨테이너에 연결하기](/docs/tasks/extend-kubernetes/http-proxy-access-api/)
|
||||
* [포트 포워딩을 사용해서 클러스터 내 애플리케이션에 접근하기](/ko/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)
|
||||
* [crictl을 사용하여 쿠버네티스 노드 조사하기](/docs/tasks/debug/debug-cluster/crictl/)
|
||||
Reference in New Issue
Block a user