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:
Kubernetes Prow Robot
2022-07-01 06:31:22 -07:00
committed by GitHub
54 changed files with 1512 additions and 712 deletions
@@ -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/)