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
@@ -59,7 +59,7 @@ no_list: true
* [쿠버네티스 클러스터에서 Sysctls 사용하기](/ko/docs/tasks/administer-cluster/sysctl-cluster/)는 관리자가 `sysctl` 커맨드라인 도구를 사용하여 커널 파라미터를 설정하는 방법에 대해 설명한다.
* [감사(audit)](/docs/tasks/debug-application-cluster/audit/)는 쿠버네티스의 감사 로그를 다루는 방법에 대해 설명한다.
* [감사(audit)](/docs/tasks/debug/debug-cluster/audit/)는 쿠버네티스의 감사 로그를 다루는 방법에 대해 설명한다.
### kubelet 보안
* [컨트롤 플레인-노드 통신](/ko/docs/concepts/architecture/control-plane-node-communication/)
@@ -461,5 +461,5 @@ kubectl edit deployment/my-nginx
## {{% heading "whatsnext" %}}
- [애플리케이션 검사 및 디버깅에 `kubectl` 을 사용하는 방법](/docs/tasks/debug-application-cluster/debug-application-introspection/)에 대해 알아본다.
- [애플리케이션 검사 및 디버깅에 `kubectl` 을 사용하는 방법](/ko/docs/tasks/debug/debug-application/debug-running-pod/)에 대해 알아본다.
- [구성 모범 사례 및 팁](/ko/docs/concepts/configuration/overview/)을 참고한다.
@@ -229,7 +229,7 @@ kubelet은 파드의 리소스 사용량을 파드
[`status`](/ko/docs/concepts/overview/working-with-objects/kubernetes-objects/#오브젝트-명세-spec-와-상태-status)에 포함하여 보고한다.
클러스터에서 선택적인 [모니터링 도구](/ko/docs/tasks/debug/debug-cluster/resource-usage-monitoring/)를
사용할 수 있다면, [메트릭 API](/ko/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#메트릭-api)에서
사용할 수 있다면, [메트릭 API](/ko/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/#metrics-api)에서
직접 또는 모니터링 도구에서 파드 리소스
사용량을 검색할 수 있다.
@@ -1290,7 +1290,7 @@ kubelet은 시크릿에 있던 기밀 데이터의 로컬 복사본을 삭제한
base64 인코딩은 암호화 수단이 _아니기 때문에_, 평문과 마찬가지로 기밀성을 제공하지 않는다.
- 시크릿 API와 통신하는 애플리케이션을 배포할 때,
[RBAC](/docs/reference/access-authn-authz/rbac/)과 같은
[인증 정책](/docs/reference/access-authn-authz/authorization/)을 사용하여
[인증 정책](/ko/docs/reference/access-authn-authz/authorization/)을 사용하여
접근을 제한해야 한다.
- 쿠버네티스 API에서, 네임스페이스 내 시크릿에 대한 `watch``list` 요청은 매우 강력한 기능이다.
시크릿 목록 조회를 가능하게 하면
@@ -1309,7 +1309,7 @@ kubelet은 시크릿에 있던 기밀 데이터의 로컬 복사본을 삭제한
가장 특권이 있는 시스템 레벨의 컴포넌트에만 이 동작을 허용한다.
- 시크릿 API와 통신하는 애플리케이션을 배포할 때,
[RBAC](/docs/reference/access-authn-authz/rbac/)과 같은
[인증 정책](/docs/reference/access-authn-authz/authorization/)을 사용하여
[인증 정책](/ko/docs/reference/access-authn-authz/authorization/)을 사용하여
접근을 제한해야 한다.
- API 서버에서, (시크릿을 포함한) 오브젝트는
{{< glossary_tooltip term_id="etcd" >}}에 저장된다. 그러므로
@@ -97,7 +97,7 @@ spec:
이것은 kubelet이 지명된 런타임클래스를 사용하여 해당 파드를 실행하도록 지시할 것이다.
만약 지명된 런타임클래스가 없거나, CRI가 상응하는 핸들러를 실행할 수 없는 경우, 파드는
`Failed` 터미널 [단계](/ko/docs/concepts/workloads/pods/pod-lifecycle/#파드의-단계-phase)로 들어간다.
에러 메시지에 상응하는 [이벤트](/docs/tasks/debug-application-cluster/debug-application-introspection/)를
에러 메시지에 상응하는 [이벤트](/ko/docs/tasks/debug/debug-application/debug-running-pod/)를
확인한다.
만약 명시된 `runtimeClassName`가 없다면, 기본 런타임 핸들러가 사용되며,
@@ -46,7 +46,7 @@ no_list: true
호스팅된 쿠버네티스 서비스 또는 매니지드 설치 환경의 배포판에서 플래그 및 구성 파일을 항상 변경할 수 있는 것은 아니다. 변경 가능한 경우 일반적으로 클러스터 관리자만 변경할 수 있다. 또한 향후 쿠버네티스 버전에서 변경될 수 있으며, 이를 설정하려면 프로세스를 다시 시작해야 할 수도 있다. 이러한 이유로 다른 옵션이 없는 경우에만 사용해야 한다.
[리소스쿼터](/ko/docs/concepts/policy/resource-quotas/), [파드시큐리티폴리시(PodSecurityPolicy)](/ko/docs/concepts/policy/pod-security-policy/), [네트워크폴리시](/ko/docs/concepts/services-networking/network-policies/) 및 역할 기반 접근 제어([RBAC](/docs/reference/access-authn-authz/rbac/))와 같은 *빌트인 정책 API(built-in Policy API)* 는 기본적으로 제공되는 쿠버네티스 API이다. API는 일반적으로 호스팅된 쿠버네티스 서비스 및 매니지드 쿠버네티스 설치 환경과 함께 사용된다. 그것들은 선언적이며 파드와 같은 다른 쿠버네티스 리소스와 동일한 규칙을 사용하므로, 새로운 클러스터 구성을 반복할 수 있고 애플리케이션과 동일한 방식으로 관리할 수 있다. 또한, 이들 API가 안정적인 경우, 다른 쿠버네티스 API와 같이 [정의된 지원 정책](/docs/reference/using-api/deprecation-policy/)을 사용할 수 있다. 이러한 이유로 인해 *구성 파일**플래그* 보다 선호된다.
[리소스쿼터](/ko/docs/concepts/policy/resource-quotas/), [파드시큐리티폴리시(PodSecurityPolicy)](/ko/docs/concepts/security/pod-security-policy/), [네트워크폴리시](/ko/docs/concepts/services-networking/network-policies/) 및 역할 기반 접근 제어([RBAC](/docs/reference/access-authn-authz/rbac/))와 같은 *빌트인 정책 API(built-in Policy API)* 는 기본적으로 제공되는 쿠버네티스 API이다. API는 일반적으로 호스팅된 쿠버네티스 서비스 및 매니지드 쿠버네티스 설치 환경과 함께 사용된다. 그것들은 선언적이며 파드와 같은 다른 쿠버네티스 리소스와 동일한 규칙을 사용하므로, 새로운 클러스터 구성을 반복할 수 있고 애플리케이션과 동일한 방식으로 관리할 수 있다. 또한, 이들 API가 안정적인 경우, 다른 쿠버네티스 API와 같이 [정의된 지원 정책](/docs/reference/using-api/deprecation-policy/)을 사용할 수 있다. 이러한 이유로 인해 *구성 파일**플래그* 보다 선호된다.
## 익스텐션
@@ -114,7 +114,7 @@ kube-controller-manager와 마찬가지로 cloud-controller-manager는 논리적
### 컨테이너 리소스 모니터링
[컨테이너 리소스 모니터링](/ko/docs/tasks/debug-application-cluster/resource-usage-monitoring/)은
[컨테이너 리소스 모니터링](/ko/docs/tasks/debug/debug-cluster/resource-usage-monitoring/)은
중앙 데이터베이스 내의 컨테이너들에 대한 포괄적인 시계열 매트릭스를 기록하고 그 데이터를 열람하기 위한 UI를 제공해 준다.
### 클러스터-레벨 로깅
@@ -652,13 +652,13 @@ spec:
### AppArmor
파드시큐리티폴리시의 어노테이션을 통해 제어된다. [AppArmor
문서](/ko/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations)를 참고하길 바란다.
문서](/ko/docs/tutorials/security/apparmor/#podsecuritypolicy-annotations)를 참고하길 바란다.
### Seccomp
쿠버네티스 v1.19부터 파드나 컨테이너의 `securityContext` 에서
`seccompProfile` 필드를 사용하여 [seccomp 프로파일 사용을
제어](/docs/tutorials/clusters/seccomp)할 수 있다. 이전 버전에서는, 파드에
제어](/docs/tutorials/security/seccomp/)할 수 있다. 이전 버전에서는, 파드에
어노테이션을 추가하여 seccomp를 제어했다. 두 버전에서 동일한 파드시큐리티폴리시를 사용하여
이러한 필드나 어노테이션이 적용되는 방식을 적용할 수 있다.
@@ -207,7 +207,7 @@ spec:
즉각적인 바인딩을 사용하는 경우,
스케줄러는 볼륨이 사용 가능해지는 즉시 해당 볼륨에 접근 가능한 노드를 선택하도록 강요받는다.
[리소스 소유권](/ko/docs/concepts/workloads/controllers/garbage-collection/#소유자-owner-와-종속-dependent) 관점에서,
[리소스 소유권](/ko/docs/concepts/architecture/garbage-collection/#owners-dependents) 관점에서,
일반 임시 스토리지를 갖는 파드는
해당 임시 스토리지를 제공하는 퍼시스턴트볼륨클레임의 소유자이다.
파드가 삭제되면, 쿠버네티스 가비지 콜렉터는 해당 PVC를 삭제하는데,
@@ -299,7 +299,7 @@ web-0이 실패할 경우 web-1은 web-0이 Running 및 Ready 상태가
{{< note >}}
`maxUnavailable` 필드는 현재 알파 단계이며
`MaxUnavailableStatefulSet`
[기능 게이트](/ko/docs/reference/commmand-line-tools-reference/feature-gates/)가 활성화된 API 서버에서만
[기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가 활성화된 API 서버에서만
동작한다.
{{< /note >}}
@@ -70,4 +70,4 @@ API에서 특별한 `ephemeralcontainers` 핸들러를 사용해서 만들어지
## {{% heading "whatsnext" %}}
* [임시 컨테이너 디버깅하기](/ko/docs/tasks/debug-application-cluster/debug-running-pod/#ephemeral-container)에 대해 알아보기.
* [임시 컨테이너 디버깅하기](/ko/docs/tasks/debug/debug-application/debug-running-pod/#ephemeral-container)에 대해 알아보기.
@@ -332,4 +332,4 @@ Active deadline은 초기화 컨테이너를 포함한다.
## {{% heading "whatsnext" %}}
* [초기화 컨테이너를 가진 파드 생성하기](/ko/docs/tasks/configure-pod-container/configure-pod-initialization/#초기화-컨테이너를-갖는-파드-생성)
* [초기화 컨테이너 디버깅](/ko/docs/tasks/debug-application-cluster/debug-init-containers/) 알아보기
* [초기화 컨테이너 디버깅](/ko/docs/tasks/debug/debug-application/debug-init-containers/) 알아보기
@@ -76,7 +76,7 @@ DELETE | delete(개별 리소스), deletecollection(리소스 모음)
쿠버네티스는 종종 전문 동사를 사용하여 부가적인 권한 인가를 확인한다. 예를 들면,
* [파드시큐리티폴리시(PodSecurityPolicy)](/ko/docs/concepts/policy/pod-security-policy/)
* [파드시큐리티폴리시(PodSecurityPolicy)](/ko/docs/concepts/security/pod-security-policy/)
* `policy` API 그룹의 `podsecuritypolicies` 리소스에 대한 `use` 동사.
* [RBAC](/docs/reference/access-authn-authz/rbac/#privilege-escalation-prevention-and-bootstrapping)
* `rbac.authorization.k8s.io` API 그룹의 `roles``clusterroles` 리소스에 대한 `bind` 동사.
@@ -607,7 +607,7 @@ kubelet과 같은 컴포넌트의 기능 게이트를 설정하려면,
플러그인의 초기 형태를 제공하였으며, 사용 중단되었다.
대안을 위해서는 [장치 플러그인](/ko/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)을
확인한다.
- `AdvancedAuditing`: [고급 감사](/docs/tasks/debug-application-cluster/audit/#advanced-audit) 기능을 활성화한다.
- `AdvancedAuditing`: [고급 감사](/docs/tasks/debug/debug-cluster/audit/#advanced-audit) 기능을 활성화한다.
- `AffinityInAnnotations`: [파드 어피니티 또는 안티-어피니티](/ko/docs/concepts/scheduling-eviction/assign-pod-node/#어피니티-affinity-와-안티-어피니티-anti-affinity)
설정을 활성화한다.
- `AllowExtTrafficLocalEndpoints`: 서비스가 외부 요청을 노드의 로컬 엔드포인트로 라우팅할 수 있도록 한다.
@@ -18,5 +18,5 @@ Kubelet과 컨테이너 런타임 사이의 통신을 위한 주요 프로토콜
쿠버네티스 컨테이너 런타임 인터페이스(CRI)는
[클러스터 컴포넌트](/ko/docs/concepts/overview/components/#노드-컴포넌트)
{{< glossary_tooltip text="kubelet" term_id="kubelet" >}}과
{{< glossary_tooltip text="container runtime" term_id="container-runtime" >}} 사이의
{{< glossary_tooltip text="container runtime" term_id="container-runtime" >}} 사이의
통신을 위한 주요 [gRPC](https://grpc.io) 프로토콜을 정의한다.
+2 -2
View File
@@ -550,7 +550,7 @@ Current user: plugins-user
* `kubectl` 레퍼런스 문서를 읽는다.
* kubectl [명령어 레퍼런스](/ko/docs/reference/kubectl/kubectl/)
* [명령줄 인자](/docs/reference/generated/kubectl/kubectl-commands/) 레퍼런스
* [`kubectl` 사용 규칙](/docs/reference/kubectl/conventions/)에 대해 알아본다.
* kubectl의 [JSONPath 지원](/docs/reference/kubectl/jsonpath/)에 대해 알아본다.
* [`kubectl` 사용 규칙](/ko/docs/reference/kubectl/conventions/)에 대해 알아본다.
* kubectl의 [JSONPath 지원](/ko/docs/reference/kubectl/jsonpath/)에 대해 알아본다.
* [플러그인으로 kubectl 확장](/ko/docs/tasks/extend-kubectl/kubectl-plugins/)에 대해 알아본다.
* 플러그인에 대해 좀 더 알아보려면, [예시 CLI 플러그인](https://github.com/kubernetes/sample-cli-plugin)을 살펴본다.
@@ -460,6 +460,6 @@ Kubectl 로그 상세 레벨(verbosity)은 `-v` 또는`--v` 플래그와 로그
* [kubectl](/ko/docs/reference/kubectl/kubectl/) 옵션을 참고한다.
* 재사용 스크립트에서 kubectl 사용 방법을 이해하기 위해 [kubectl 사용](/ko/docs/reference/kubectl/conventions/)을 참고한다.
* 재사용 스크립트에서 kubectl 사용 방법을 이해하기 위해 [kubectl 사용 규칙](/ko/docs/reference/kubectl/conventions/)을 참고한다.
* 더 많은 커뮤니티 [kubectl 치트시트](https://github.com/dennyzhang/cheatsheet-kubernetes-A4)를 확인한다.
@@ -187,7 +187,7 @@ kubectl exec -ti nginx-app-5jyvm -- /bin/sh
# exit
```
자세한 내용은 [실행 중인 컨테이너의 셸 얻기](/ko/docs/tasks/debug-application-cluster/get-shell-running-container/)를 참고한다.
자세한 내용은 [실행 중인 컨테이너의 셸 얻기](/ko/docs/tasks/debug/debug-application/get-shell-running-container/)를 참고한다.
## docker logs
+1 -1
View File
@@ -9,7 +9,7 @@ weight: 30
kubectl은 쿠버네티스 클러스터 관리자를 제어한다.
자세한 정보는 [kubectl 개요](/ko/docs/reference/kubectl/overview/)를 확인한다.
자세한 정보는 [kubectl 개요](/ko/docs/reference/kubectl/)를 확인한다.
```
kubectl [flags]
@@ -461,7 +461,7 @@ kubelet이 "외부" 클라우드 공급자에 의해 실행되었다면 노드
## container.seccomp.security.alpha.kubernetes.io/[이름] {#container-seccomp-security-alpha-kubernetes-io}
이 어노테이션은 쿠버네티스 v1.19부터 사용 중단되었으며 v1.25에서는 작동하지 않을 것이다.
[seccomp를 이용하여 컨테이너의 syscall 제한하기](/docs/tutorials/clusters/seccomp/) 튜토리얼에서
[seccomp를 이용하여 컨테이너의 syscall 제한하기](/docs/tutorials/security/seccomp/) 튜토리얼에서
seccomp 프로파일을 파드 또는 파드 내 컨테이너에 적용하는 단계를 확인한다.
튜토리얼에서는 쿠버네티스에 seccomp를 설정하기 위해 사용할 수 있는 방법을 소개하며,
이는 파드의 `.spec` 내에 `securityContext` 를 설정함으로써 가능하다.
@@ -197,7 +197,7 @@ etcd 백업 계획을 세우려면
스크립트를 구성할 수 있는 가상화 플랫폼이 있다.
- *노드 헬스 체크 구성*: 중요한 워크로드의 경우,
해당 노드에서 실행 중인 노드와 파드의 상태가 정상인지 확인하고 싶을 것이다.
[Node Problem Detector](/docs/tasks/debug-application-cluster/monitor-node-health/)
[Node Problem Detector](/docs/tasks/debug/debug-cluster/monitor-node-health/)
데몬을 사용하면 노드가 정상인지 확인할 수 있다.
## 프로덕션 사용자 관리
@@ -36,7 +36,7 @@ _dockershim_ 이라는 구성 요소를 사용하여 도커 엔진과의 직접
더 이상 쿠버네티스에 포함되지 않는다(이 제거는
v1.20 릴리스의 일부로 [공지](/blog/2020/12/08/kubernetes-1-20-release-announcement/#dockershim-deprecation)되었다).
이 제거가 어떻게 영향을 미치는지 알아보려면
[Dockershim 사용 중단이 영향을 미치는지 확인하기](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-deprecation-affects-you/) 문서를 확인한다.
[Dockershim 사용 중단이 영향을 미치는지 확인하기](/docs/tasks/administer-cluster/migrating-from-dockershim/check-if-dockershim-removal-affects-you/) 문서를 확인한다.
dockershim을 사용하던 환경에서 이전(migrating)하는 방법을 보려면,
[dockershim에서 이전하기](/docs/tasks/administer-cluster/migrating-from-dockershim/)를 확인한다.
@@ -98,9 +98,9 @@ kubeadm은 에러를 반환하고 사용자가 어떤 것을 사용할지를 명
{{< note >}}
도커 엔진은 컨테이너 런타임이 쿠버네티스와 호환되기 위한 요구 사항인
[CRI](/docs/concepts/architecture/cri/)를 만족하지 않는다.
[CRI](/ko/docs/concepts/architecture/cri/)를 만족하지 않는다.
이러한 이유로, 추가 서비스인 [cri-dockerd](https://github.com/Mirantis/cri-dockerd)가 설치되어야 한다.
cri-dockerd는 쿠버네티스 버전 1.24부터 kubelet에서 [제거](/dockershim)된
cri-dockerd는 쿠버네티스 버전 1.24부터 kubelet에서 [제거](/dockershim/)된
기존 내장 도커 엔진 지원을 기반으로 한 프로젝트이다.
{{< /note >}}
@@ -830,7 +830,7 @@ DNS, 라우트, 메트릭과 같은 많은 구성은 리눅스에서와 같이 /
[RunAsUsername](/ko/docs/tasks/configure-pod-container/configure-runasusername/)은
컨테이너 프로세스를 노드 기본 사용자로 실행하기 위해 윈도우 파드 또는
컨테이너에 지정할 수 있다. 이것은
[RunAsUser](/ko/docs/concepts/policy/pod-security-policy/#사용자-및-그룹)와 거의 동일하다.
[RunAsUser](/ko/docs/concepts/security/pod-security-policy/#사용자-및-그룹)와 거의 동일하다.
SELinux, AppArmor, Seccomp, 기능(POSIX 기능)과 같은
리눅스 특유의 파드 시큐리티 컨텍스트 권한은 지원하지 않는다.
@@ -997,8 +997,8 @@ PodSecurityContext 필드는 윈도우에서 작동하지 않는다. 참조를
## 도움 받기 및 트러블슈팅 {#troubleshooting}
쿠버네티스 클러스터 트러블슈팅을 위한 기본
도움말은
[섹션](/ko/docs/tasks/debug-application-cluster/troubleshooting/)에서 먼저 찾아야 한다. 이
도움말은
[섹션](/ko/docs/tasks/debug/debug-cluster/)에서 먼저 찾아야 한다. 이
섹션에는 몇 가지 추가 윈도우 관련 트러블슈팅 도움말이 포함되어 있다.
로그는 쿠버네티스에서 트러블슈팅하는데 중요한 요소이다. 다른
기여자로부터 트러블슈팅 지원을 구할 때마다 이를 포함해야
@@ -214,7 +214,7 @@ API 서버를 찾고 인증하는 방식이 약간 다를 수 있다.
이전 섹션에서는 쿠버네티스 API 서버에 연결하는 방법을 소개하였다.
쿠버네티스 클러스터에서 실행되는 다른 서비스에 연결하는 방법은
[클러스터 서비스에 접근](/ko/docs/tasks/administer-cluster/access-cluster-services/) 페이지를 참조한다.
[클러스터 서비스에 접근](/ko/docs/tasks/access-application-cluster/access-cluster-services/) 페이지를 참조한다.
## redirect 요청하기
@@ -208,9 +208,9 @@ kubelet이 CRI 호환 엔드포인트를 통해 도커와 통신하기 위해
{{< note >}}
도커 엔진은 컨테이너 런타임이 쿠버네티스와 호환되기 위한 요구 사항인
[CRI](/docs/concepts/architecture/cri/)를 만족하지 않는다.
[CRI](/ko/docs/concepts/architecture/cri/)를 만족하지 않는다.
이러한 이유로, 추가 서비스인 [cri-dockerd](https://github.com/Mirantis/cri-dockerd)가 설치되어야 한다.
cri-dockerd는 쿠버네티스 버전 1.24부터 kubelet에서 [제거](/dockershim)된
cri-dockerd는 쿠버네티스 버전 1.24부터 kubelet에서 [제거](/dockershim/)된
기존 내장 도커 엔진 지원을 기반으로 한 프로젝트이다.
{{< /note >}}
@@ -85,4 +85,4 @@ init-demo 파드 내 실행 중인 nginx 컨테이너의 셸을 실행한다.
대해 배우기.
* [초기화 컨테이너](/ko/docs/concepts/workloads/pods/init-containers/)에 대해 배우기.
* [볼륨](/ko/docs/concepts/storage/volumes/)에 대해 배우기.
* [초기화 컨테이너 디버깅](/ko/docs/tasks/debug-application-cluster/debug-init-containers/)에 대해 배우기.
* [초기화 컨테이너 디버깅](/ko/docs/tasks/debug/debug-application/debug-init-containers/)에 대해 배우기.
@@ -182,7 +182,7 @@ static-web 1/1 Running 0 2m
```
{{< note >}}
Kubelet에 API 서버에서 미러 파드를 생성할 수 있는 권한이 있는지 미리 확인해야 한다. 그렇지 않을 경우 API 서버에 의해서 생성 요청이 거부된다. [파드 시큐리티 어드미션](/docs/concepts/security/pod-security-admission/) 및 [파드시큐리티폴리시(PodSecurityPolicy)](/ko/docs/concepts/policy/pod-security-policy/)를 확인한다.
Kubelet에 API 서버에서 미러 파드를 생성할 수 있는 권한이 있는지 미리 확인해야 한다. 그렇지 않을 경우 API 서버에 의해서 생성 요청이 거부된다. [파드 시큐리티 어드미션](/docs/concepts/security/pod-security-admission/) 및 [파드시큐리티폴리시(PodSecurityPolicy)](/ko/docs/concepts/security/pod-security-policy/)를 확인한다.
{{< /note >}}
스태틱 파드에 있는 {{< glossary_tooltip term_id="label" text="레이블" >}} 은
@@ -1,6 +0,0 @@
---
title: "모니터링, 로깅, 그리고 디버깅"
description: 모니터링 및 로깅을 설정하여 클러스터 문제를 해결하거나, 컨테이너화된 애플리케이션을 디버깅한다.
weight: 80
---
@@ -1,124 +0,0 @@
---
title: 클러스터 트러블슈팅
content_type: concept
---
<!-- overview -->
이 문서는 클러스터 트러블슈팅에 대해 설명한다. 사용자가 겪고 있는 문제의 근본 원인으로서 사용자의 애플리케이션을
이미 배제했다고 가정한다.
애플리케이션 디버깅에 대한 팁은 [애플리케이션 트러블슈팅 가이드](/docs/tasks/debug-application-cluster/debug-application/)를 참조한다.
자세한 내용은 [트러블슈팅 문서](/ko/docs/tasks/debug-application-cluster/troubleshooting/)를 참조한다.
<!-- body -->
## 클러스터 나열하기
클러스터에서 가장 먼저 디버그해야 할 것은 노드가 모두 올바르게 등록되었는지 여부이다.
다음을 실행한다.
```shell
kubectl get nodes
```
그리고 보일 것으로 예상되는 모든 노드가 존재하고 모두 `Ready` 상태인지 확인한다.
클러스터의 전반적인 상태에 대한 자세한 정보를 얻으려면 다음을 실행할 수 있다.
```shell
kubectl cluster-info dump
```
## 로그 보기
현재로서는 클러스터를 더 깊이 파고들려면 관련 머신에서 로그 확인이 필요하다. 관련 로그 파일
위치는 다음과 같다. (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 소프트웨어 오류
@@ -1,105 +0,0 @@
---
title: 파드와 레플리케이션컨트롤러(ReplicationController) 디버그하기
content_type: task
---
<!-- overview -->
이 페이지에서는 파드와 레플리케이션컨트롤러를 디버깅하는 방법을 소개한다.
## {{% heading "prerequisites" %}}
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
* 사용자는
{{< glossary_tooltip text="파드" term_id="pod" >}} 기본 사항과 파드의
[라이프사이클](/ko/docs/concepts/workloads/pods/pod-lifecycle/)에 대해 잘 알고 있어야 한다.
<!-- steps -->
## 파드 디버깅
파드 디버깅의 첫 번째 단계는 파드를 살펴 보는 것이다. 다음의 명령어를
사용하여 파드의 현재 상태와 최근 이벤트를 점검한다.
```shell
kubectl describe pods ${POD_NAME}
```
파드 내부 컨테이너의 상태를 확인한다. 모두 `Running` 상태인가?
최근에 재시작 되었는가?
파드의 상태에 따라 디버깅을 계속한다.
### 파드가 pending 상태로 유지
파드가 `Pending` 상태로 멈춰 있는 경우는, 노드에 스케줄 될 수 없음을 의미한다.
일반적으로 이것은 어떤 유형의 리소스가 부족하거나 스케줄링을 방해하는 다른 요인 때문이다.
상단의 `kubectl describe ...` 명령의 결과를 확인하자.
파드를 스케줄 할 수 없는 이유에 대한 스케줄러의 메세지가 있어야 한다.
이유는 다음과 같다.
#### 부족한 리소스
사용자 클러스터의 CPU 나 Memory의 공급이 소진되었을 수 있다. 이 경우
몇 가지 방법을 시도할 수 있다.
* 클러스터에 노드를 더 추가하기.
* pending 상태인 파드를 위한 공간을 확보하기 위해
[불필요한 파드 종료하기](/ko/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination)
* 파드가 노드보다 크지 않은지 확인한다. 예를 들어 모든
노드가 `cpu:1` 의 용량을 가지고 있을 경우, `cpu: 1.1` 을 요청하는 파드는
절대 스케줄 될 수 없다.
사용자는 `kubectl get nodes -o <format>` 명령으로 노드의
용량을 점검할 수 있다. 다음은 필요한 정보를 추출하는 몇 가지
명령의 예이다.
```shell
kubectl get nodes -o yaml | egrep '\sname:|cpu:|memory:'
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, cap: .status.capacity}'
```
[리소스 쿼터](/ko/docs/concepts/policy/resource-quotas/)
기능은 사용할 수 있는 전체 리소스의 양을 제한하도록 설정할 수 있다.
네임스페이스와 함께 사용하면,
한 팀이 모든 리소스를 점유하는 것을 방지할 수 있다.
#### hostPort 사용하기
파드를 `hostPort` 에 바인딩 할 때 파드를 스케줄링 할 수 있는
위치는 제한되어 있다. 대부분의 경우 `hostPort` 는 불필요하다. 서비스 오브젝트를
사용하여 파드를 노출하도록 한다. `hostPort` 가 필요한 경우
컨테이너 클러스터에 있는 노드의 수만큼 파드를 스케줄 할 수 있다.
### 파드가 waiting 상태로 유지
파드가 `Waiting` 상태에서 멈춘 경우, 워커 노드에 스케줄 되었지만, 해당 장비에서 사용할 수 없다.
거듭 강조하지만, `kubectl describe ...` 의 정보는 유익하게 사용되어야 한다.
`Waiting` 파드의 가장 일반적인 원인은 이미지를 가져오지 못하는 경우이다.
확인해야 할 3가지 사항이 있다.
* 이미지 이름이 올바른지 확인한다.
* 이미지를 저장소에 푸시하였는가?
* 이미지가 풀 될 수 있는지 보기 위해, 사용자의 장비에서 `docker pull <image>` 를 수동으로
실행한다.
### 파드가 손상(crashing)되었거나 양호하지 않을(unhealthy) 경우
일단 사용자의 파드가 스케줄 되면, [구동중인 파드 디버그하기](/ko/docs/tasks/debug-application-cluster/debug-running-pod/)에
기술된 메서드를 디버깅에 사용할 수 있다.
## 레플리케이션컨트롤러 디버깅
레플리케이션컨트롤러는 매우 간단하다. 이 오브젝트는 파드를 만들거나
만들 수 없는 경우뿐이다. 만약 파드를 만들 수 없는 경우,
[위의 지침](#파드-디버깅)을 참조하여 파드를 디버그한다.
사용자는 `kubectl describe rc ${CONTROLLER_NAME}` 을 사용하여 레플리케이션 컨트롤러와
관련된 이벤트를 검사할 수도 있다.
@@ -1,332 +0,0 @@
---
title: 동작 중인 파드 디버그
content_type: task
---
<!-- overview -->
이 페이지는 노드에서 동작 중인(혹은 크래시된) 파드를 디버그하는 방법에 대해 설명한다.
## {{% heading "prerequisites" %}}
* 여러분의 {{< glossary_tooltip text="파드" term_id="pod" >}}는 이미 스케줄링 되어
동작하고 있을 것이다. 만약 파드가 아직 동작중이지 않다면, [애플리케이션
트러블슈팅](/docs/tasks/debug-application-cluster/debug-application/)을 참고한다.
* 일부 고급 디버깅 과정에서는 해당 파드가 어떤 노드에서 동작하고 있는지
알아야 하고, 해당 노드에서 쉘 명령어를 실행시킬 수 있어야 한다.
`kubectl`을 사용하는 일반적인 디버깅 과정에서는 이러한 접근 권한이 필요하지 않다.
<!-- steps -->
## 파드의 로그 확인하기 {#examine-pod-logs}
먼저, 확인하고자 하는 컨테이너의 로그를 확인한다.
```shell
kubectl logs ${POD_NAME} ${CONTAINER_NAME}
```
만약 컨테이너가 이전에 크래시 되었다면, 다음의 명령을 통해 컨테이너의 크래시 로그를 살펴볼 수 있다.
```shell
kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
```
## exec를 통해 컨테이너 디버깅하기 {#container-exec}
만약 {{< glossary_tooltip text="컨테이너 이미지" term_id="image" >}}에
디버깅 도구가 포함되어 있다면, `kubectl exec`을 통해 특정 컨테이너에서 해당 명령들을
실행할 수 있다. (리눅스나 윈도우 OS를 기반으로 만들어진 이미지에는 대부분 디버깅 도구를 포함하고
있다.)
```shell
kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}
```
{{< note >}}
`-c ${CONTAINER_NAME}` 인자는 선택적이다. 만약 하나의 컨테이너만 포함된 파드라면 해당 옵션을 생략할 수 있다.
{{< /note >}}
예를 들어, 동작 중인 카산드라 파드의 로그를 살펴보기 위해서는 다음과 같은 명령을 실행할 수 있다.
```shell
kubectl exec cassandra -- cat /var/log/cassandra/system.log
```
`kubectl exec``-i``-t` 옵션을 사용해서 터미널에서 접근할 수 있는 쉘을 실행시킬 수도 있다.
예를 들면 다음과 같다.
```shell
kubectl exec -it cassandra -- sh
```
더욱 상세한 내용은 다음 [동작중인 컨테이너의 쉘에 접근하기](
/ko/docs/tasks/debug-application-cluster/get-shell-running-container/)를 참고하라.
## 임시(ephemeral) 디버그 컨테이너를 사용해서 디버깅하기 {#ephemeral-container}
{{< feature-state state="beta" for_k8s_version="v1.23" >}}
컨테이너가 크래시 됐거나
[distroless 이미지](https://github.com/GoogleContainerTools/distroless)처럼
컨테이너 이미지에 디버깅 도구를 포함하고 있지 않아 `kubectl exec`로는 충분하지 않은 경우에는
{{< glossary_tooltip text="임시(Ephemeral) 컨테이너" term_id="ephemeral-container" >}}를 사용하는 것이
인터랙티브한 트러블슈팅에 유용하다.
### 임시 컨테이너를 사용한 디버깅 예시 {#ephemeral-container-example}
`kubectl debug` 명령어를 사용해서 동작 중인 파드에 임시 컨테이너를 추가할 수 있다.
먼저, 다음과 같이 파드를 추가한다.
```shell
kubectl run ephemeral-demo --image=k8s.gcr.io/pause:3.1 --restart=Never
```
이 섹션의 예시에서는 디버깅 도구가 포함되지 않은 이미지의 사례를 보여드리기 위해
`pause` 컨테이너 이미지를 사용했는데, 이 대신 어떠한 이미지를 사용해도
될 것이다.
만약 `kubectl exec`을 통해 쉘을 생성하려 한다면 다음과 같은 에러를
확인할 수 있을 텐데, 그 이유는 이 이미지에 쉘이 존재하지 않기 때문이다.
```shell
kubectl exec -it ephemeral-demo -- sh
```
```
OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown
```
이 명령어 대신 `kubectl debug`을 사용해서 디버깅 컨테이너를 생성할 수 있다.
만약 `-i`/`--interactive` 인자를 사용한다면, `kubectl`은 임시
컨테이너의 콘솔에 자동으로 연결할 것이다.
```shell
kubectl debug -it ephemeral-demo --image=busybox --target=ephemeral-demo
```
```
Defaulting debug container name to debugger-8xzrl.
If you don't see a command prompt, try pressing enter.
/ #
```
이 명령어는 새로운 busybox 컨테이너를 추가하고 해당 컨테이너로 연결한다. `--target`
파라미터를 사용하면 다른 컨테이너의 프로세스 네임스페이스를 대상으로 하게 된다. 여기서는
이 옵션이 꼭 필요한데, `kubectl run`이 생성하는 파드에 대해
[프로세스 네임스페이스 공유](/docs/tasks/configure-pod-container/share-process-namespace/)를
활성화하지 않기 때문이다.
{{< note >}}
`--target` 파라미터는 사용 중인 {{< glossary_tooltip text="컨테이너 런타임" term_id="container-runtime" >}}에서
지원해야지만 사용할 수 있다. 만일 지원되지 않는다면,
임시 컨테이너가 시작되지 않을 수 있거나 독립적인 프로세스
네임스페이스를 가지고 시작될 수 있다.
{{< /note >}}
`kubectl describe` 명령을 사용하면 새롭게 생성된 임시 컨테이너의 상태를 확인할 수 있다.
```shell
kubectl describe pod ephemeral-demo
```
```
...
Ephemeral Containers:
debugger-8xzrl:
Container ID: docker://b888f9adfd15bd5739fefaa39e1df4dd3c617b9902082b1cfdc29c4028ffb2eb
Image: busybox
Image ID: docker-pullable://busybox@sha256:1828edd60c5efd34b2bf5dd3282ec0cc04d47b2ff9caa0b6d4f07a21d1c08084
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 12 Feb 2020 14:25:42 +0100
Ready: False
Restart Count: 0
Environment: <none>
Mounts: <none>
...
```
디버깅이 다 끝나면 `kubectl delete`을 통해 파드를 제거할 수 있다.
```shell
kubectl delete pod ephemeral-demo
```
## 파드의 복제본을 이용해서 디버깅하기
때때로 파드의 설정 옵션에 따라 특정 상황에서 트러블슈팅을 하기가 어려울 수 있다.
예를 들어, 만일 여러분의 컨테이너 이미지가 쉘을 포함하고 있지 않거나, 여러분의
애플리케이션이 컨테이너 시작에서 크래시가 발생한다면 `kubectl exec`을 이용해서
컨테이너를 트러블슈팅할 수 없을 수 있다. 이러한 상황에서는 `kubectl debug`을 사용해서
파드의 복제본을 디버깅을 위한 추가적인 설정 옵션과 함께 생성할 수 있다.
### 새 컨테이너와 함께 파드의 복제본 생성하기
만일 여러분의 애플리케이션이 동작은 하고 있지만 예상과는 다르게 동작하는 경우,
파드의 복제본에 새로운 컨테이너를 추가함으로써 추가적인 트러블슈팅 도구들을
파드에 함께 추가할 수 있다.
가령, 여러분의 애플리케이션 컨테이너 이미지는 `busybox`를 기반으로 하고 있는데
여러분은 `busybox`에는 없는 디버깅 도구를 필요로 한다고 가정해 보자. 이러한
시나리오는 `kubectl run` 명령을 통해 시뮬레이션 해볼 수 있다.
```shell
kubectl run myapp --image=busybox --restart=Never -- sleep 1d
```
다음의 명령을 실행시켜 디버깅을 위한 새로운 우분투 컨테이너와 함께 `myapp-debug`이란
이름의 `myapp` 컨테이너 복제본을 생성할 수 있다.
```shell
kubectl debug myapp -it --image=ubuntu --share-processes --copy-to=myapp-debug
```
```
Defaulting debug container name to debugger-w7xmf.
If you don't see a command prompt, try pressing enter.
root@myapp-debug:/#
```
{{< note >}}
* 만일 여러분이 새로 생성되는 컨테이너의 이름을 `--container` 플래그와 함께 지정하지 않는다면,
`kubectl debug`는 자동으로 새로운 컨테이너 이름을 생성한다.
* `-i` 플래그를 사용하면 `kubectl debug` 명령이 새로운 컨테이너에 기본적으로 연결되게 된다.
이러한 동작은 `--attach=false`을 지정하여 방지할 수 있다. 만일 여러분의 세션이
연결이 끊어진다면 `kubectl attach`를 사용해서 다시 연결할 수 있다.
* `--share-processes` 옵션은 이 파드에 있는 컨테이너가 해당 파드에 속한 다른 컨테이너의
프로세스를 볼 수 있도록 한다. 이 옵션이 어떻게 동작하는지에 대해 더 알아보기 위해서는
다음의 [파드의 컨테이너 간 프로세스 네임스페이스 공유](
/docs/tasks/configure-pod-container/share-process-namespace/)를 참고하라.
{{< /note >}}
사용이 모두 끝나면, 디버깅에 사용된 파드를 잊지 말고 정리한다.
```shell
kubectl delete pod myapp myapp-debug
```
### 명령어를 변경하며 파드의 복제본 생성하기
때때로 컨테이너의 명령어를 변경하는 것이 유용한 경우가 있는데, 예를 들면 디버그 플래그를 추가하기
위해서나 애플리케이션이 크래시 되는 경우이다.
다음의 `kubectl run` 명령을 통해 즉각적으로 크래시가 발생하는 애플리케이션의
사례를 시뮬레이션해 볼 수 있다.
```
kubectl run --image=busybox myapp -- false
```
`kubectl describe pod myapp` 명령을 통해 이 컨테이너에 크래시가 발생하고 있음을 확인할 수 있다.
```
Containers:
myapp:
Image: busybox
...
Args:
false
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Error
Exit Code: 1
```
이러한 경우에 `kubectl debug`을 통해 명령어를 지정함으로써 해당 파드의
복제본을 인터랙티브 쉘로 생성할 수 있다.
```
kubectl debug myapp -it --copy-to=myapp-debug --container=myapp -- sh
```
```
If you don't see a command prompt, try pressing enter.
/ #
```
이제 인터랙티브 쉘에 접근할 수 있으니 파일 시스템 경로를 확인하거나
동작 중인 컨테이너의 명령어를 직접 확인하는 등의 작업이 가능하다.
{{< note >}}
* 특정 컨테이너의 명령어를 변경하기 위해서는 `--container` 옵션을 통해 해당 컨테이너의
이름을 지정해야만 한다. 이름을 지정하지 않는다면 `kubectl debug`은 이전에 지정한 명령어를
그대로 사용해서 컨테이너를 생성할 것이다.
* 기본적으로 `-i` 플래그는 `kubectl debug` 명령이 컨테이너에 바로 연결되도록 한다.
이러한 동작을 방지하기 위해서는 `--attach=false` 옵션을 지정할 수 있다. 만약 여러분이 세션이
종료된다면 `kubectl attach` 명령을 통해 다시 연결할 수 있다.
{{< /note >}}
사용이 모두 끝나면, 디버깅에 사용된 파드들을 잊지 말고 정리한다.
```shell
kubectl delete pod myapp myapp-debug
```
### 컨테이너 이미지를 변경하며 파드의 복제본 생성하기
특정한 경우에 여러분은 제대로 동작하지 않는 파드의 이미지를
기존 프로덕션 컨테이너 이미지에서 디버깅 빌드나 추가적인 도구를 포함한
이미지로 변경하고 싶을 수 있다.
이 사례를 보여주기 위해 `kubectl run` 명령을 통해 파드를 생성하였다.
```
kubectl run myapp --image=busybox --restart=Never -- sleep 1d
```
여기서는 `kubectl debug` 명령을 통해 해당 컨테이너 이미지를 `ubuntu`로 변경하며
복제본을 생성하였다.
```
kubectl debug myapp --copy-to=myapp-debug --set-image=*=ubuntu
```
`--set-image`의 문법은 `kubectl set image`와 동일하게 `container_name=image`
형식의 문법을 사용한다. `*=ubuntu`라는 의미는 모든 컨테이너의 이미지를 `ubuntu`
변경하겠다는 의미이다.
사용이 모두 끝나면, 디버깅에 사용된 파드를 잊지 말고 정리한다.
```shell
kubectl delete pod myapp myapp-debug
```
## 노드의 쉘을 사용해서 디버깅하기 {#node-shell-session}
만약 위의 어떠한 방법도 사용할 수 없다면, 파드가 현재 동작 중인 노드를 찾아
호스트의 네임스페이스로 동작하는 특권 파드를 생성할 수 있다.
다음 `kubectl debug` 명령을 통해 해당 노드에서 인터랙티브한 쉘을 생성할 수 있다.
```shell
kubectl debug node/mynode -it --image=ubuntu
```
```
Creating debugging pod node-debugger-mynode-pdx84 with container debugger on node mynode.
If you don't see a command prompt, try pressing enter.
root@ek8s:/#
```
노드에서 디버깅 세션을 생성할 때 유의해야 할 점은 다음과 같다.
* `kubectl debug`는 노드의 이름에 기반해 새로운 파드의 이름을
자동으로 생성한다.
* 컨테이너는 호스트 네임스페이스(IPC, 네트워크, PID 네임스페이스)에서 동작한다.
* 노드의 루트 파일시스템은 `/host`에 마운트된다.
사용이 모두 끝나면, 디버깅에 사용된 파드를 잊지 말고 정리한다.
```shell
kubectl delete pod node-debugger-mynode-pdx84
```
@@ -1,76 +0,0 @@
---
title: 리소스 메트릭 파이프라인
content_type: concept
---
<!-- overview -->
컨테이너 CPU 및 메모리 사용량과 같은 리소스 사용량 메트릭은
쿠버네티스의 메트릭 API를 통해 사용할 수 있다. 이 메트릭은
`kubectl top` 커맨드 사용하여 사용자가 직접적으로 액세스하거나,
Horizontal Pod Autoscaler 같은 클러스터의 컨트롤러에서 결정을 내릴 때 사용될 수 있다.
<!-- body -->
## 메트릭 API
메트릭 API를 통해, 주어진 노드나 파드에서 현재 사용중인
리소스의 양을 알 수 있다. 이 API는 메트릭 값을 저장하지
않으므로, 예를 들어, 지정된 노드에서 10분 전에 사용된 리소스의 양을
가져오는 것과 같은 일을 할 수는 없다.
이 API와 다른 API는 차이가 없다.
- 다른 쿠버네티스 API의 엔드포인트와 같이 `/apis/metrics.k8s.io/` 하위 경로에서 발견될 수 있다
- 동일한 보안, 확장성 및 신뢰성 보장을 제공한다
[k8s.io/metrics](https://github.com/kubernetes/metrics/blob/master/pkg/apis/metrics/v1beta1/types.go)
리포지터리에서 이 API를 정의하고 있다. 여기에서 이 API에 대한 더 상세한 정보를 찾을 수 있다.
{{< note >}}
이 API를 사용하려면 메트릭 서버를 클러스터에 배포해야 한다. 그렇지 않으면 사용할 수 없다.
{{< /note >}}
## 리소스 사용량 측정
### CPU
CPU는 일정 기간 동안
[CPU 코어](/ko/docs/concepts/configuration/manage-resources-containers/#cpu의-의미)에서
평균 사용량으로 리포트된다. 이 값은 커널(리눅스와 윈도우 커널 모두)에서 제공하는
누적 CPU 카운터보다 높은 비율을 적용해서 얻는다.
kubelet은 비율 계산에 사용할 윈도우를 선택한다.
### 메모리
메모리는 메트릭이 수집된 순간 작업 집합으로 리포트 된다.
이상적인 환경에서 "작업 집합(working set)"은 압박(memory pressure)에서 풀려날 수 없는 사용 중인(in-use) 메모리의 양이다.
그러나 작업 집합의 계산은 호스트 OS에 따라 다르며, 일반적으로 휴리스틱스를 사용해서 평가한다.
쿠버네티스는 스왑(swap)을 지원하지 않기 때문에 모든 익명(파일로 백업되지 않은) 메모리를 포함한다.
호스트 OS가 항상 이러한 페이지를 회수할 수 없기 때문에 메트릭에는 일반적으로 일부 캐시된(파일 백업) 메모리도 포함된다.
## 메트릭 서버
[메트릭 서버](https://github.com/kubernetes-sigs/metrics-server)는 클러스터 전역에서 리소스 사용량 데이터를 집계한다.
`kube-up.sh` 스크립트에 의해 생성된 클러스터에는 기본적으로 메트릭 서버가
디플로이먼트 오브젝트로 배포된다. 만약 다른 쿠버네티스 설치 메커니즘을 사용한다면, 제공된
[디플로이먼트 components.yaml](https://github.com/kubernetes-sigs/metrics-server/releases) 파일을 사용하여 메트릭 서버를 배포할 수 있다.
메트릭 서버는 각 노드에서 [Kubelet](/docs/reference/command-line-tools-reference/kubelet/)에 의해
노출된 Summary API에서 메트릭을 수집하고, [쿠버네티스 aggregator](/ko/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/)를
통해 메인 API 서버에 등록된다.
[설계 문서](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/metrics-server.md)에서
메트릭 서버에 대해 자세하게 배울 수 있다.
### 요약(Summary) API 소스
[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)에 기록한다.
1.23 이전에는 이러한 자원들은 기본적으로 [cAdvisor](https://github.com/google/cadvisor)에 의해 수집되었다.
그러나, 1.23에서 `PodAndContainerStatsFromCRI` 기능 게이트가 추가되면서, 컨테이너 및 파드 수준 통계를 CRI 구현에서 수집할 수 있게 되었다.
참고: 이를 위해서는 CRI 구현에서도 이 기능을 지원해야 한다(containerd >= 1.6.0, CRI-O >= 1.23.0).
@@ -1,9 +1,12 @@
---
title: "모니터링, 로깅, 및 디버깅"
description: 클러스터를 트러블슈팅할 수 있도록 모니터링과 로깅을 설정하거나, 컨테이너화된 애플리케이션을 디버깅한다.
weight: 20
content_type: concept
title: 트러블슈팅하기
no_list: true
---
<!-- overview -->
@@ -11,9 +14,9 @@ title: 트러블슈팅하기
때때로 문제가 발생할 수 있다. 이 가이드는 이러한 상황을 해결하기 위해 작성되었다. 문제 해결에는
다음 두 가지를 참고해 볼 수 있다.
* [애플리케이션 트러블슈팅하기](/docs/tasks/debug-application-cluster/debug-application/) - 쿠버네티스에
* [애플리케이션 디버깅하기](/ko/docs/tasks/debug/debug-application/) - 쿠버네티스에
코드를 배포하였지만 제대로 동작하지 않는 사용자들에게 유용한 가이드이다.
* [클러스터 트러블슈팅하기](/ko/docs/tasks/debug-application-cluster/debug-cluster/) - 쿠버네티스 클러스터에
* [클러스터 디버깅하기](/ko/docs/tasks/debug/debug-cluster/) - 쿠버네티스 클러스터에
문제를 겪고 있는 클러스터 관리자 혹은 기분이 나쁜 사람들에게 유용한 가이드이다.
여러분이 현재 사용중인 릴리스에 대한 알려진 이슈들을 다음의 [릴리스](https://github.com/kubernetes/kubernetes/releases)
@@ -35,7 +38,7 @@ title: 트러블슈팅하기
[튜토리얼](/ko/docs/tutorials/)은 실무, 산업 특화 혹은 종단간 개발에 특화된 시나리오를 통해 차근차근 설명한다.
[레퍼런스](/ko/docs/reference/) 섹션에서는
[쿠버네티스 API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/)와
[`kubectl`](/ko/docs/reference/kubectl/overview/)과 같은 커맨드 라인 인터페이스(CLI)에 대한
[`kubectl`](/ko/docs/reference/kubectl/)과 같은 커맨드 라인 인터페이스(CLI)에 대한
상세한 설명을 다룬다.
## 도와주세요! 내 질문이 다뤄지지 않았어요! 도움이 필요해요!
@@ -45,8 +48,9 @@ title: 트러블슈팅하기
여러분들이 겪고 있는 문제와 동일한 문제에 대한 도움을 위해 커뮤니티의 다른 사람들이 이미
질문을 올렸을 수 있다. 쿠버네티스 팀은
[쿠버네티스 태그가 등록된 글](https://stackoverflow.com/questions/tagged/kubernetes)들을 모니터링하고 있다.
발생한 문제 도움이 되는 질문이 없다면,
[새로운 질문](https://stackoverflow.com/questions/ask?tags=kubernetes)을 올려라!
발생한 문제 도움이 되는 기존 질문이 없다면,
**[해당 질문이 스택 오버플로우에 적합한지](https://stackoverflow.com/help/on-topic)와 [새로운 질문을 올리는 방법](https://stackoverflow.com/help/how-to-ask)에 대한 가이드를 읽은 뒤에**
[새로운 질문](https://stackoverflow.com/questions/ask?tags=kubernetes)을 올리자!
### 슬랙
@@ -102,6 +106,3 @@ Turkey(터키) | [`#tr-users`](https://kubernetes.slack.com/messages/tr-users),
* 쿠버네티스 버전: `kubectl version`
* 클라우드 프로바이더, OS 배포판, 네트워크 구성, 및 도커 버전
* 문제를 재현하기 위한 절차
@@ -0,0 +1,7 @@
---
title: "애플리케이션 트러블슈팅하기"
description: 일반적인 컨테이너화된 애플리케이션 이슈를 디버깅한다.
weight: 20
---
이 문서는 컨테이너화된 애플리케이션의 이슈를 해결하기 위한 자원을 담고 있다. 쿠버네티스 리소스(예: 파드, 서비스, 스테이트풀셋)의 일반적 이슈, 컨테이너 종료 메시지 이해에 대한 조언, 실행 중인 컨테이너를 디버그하는 방법 등을 다룬다.
@@ -1,6 +1,15 @@
---
title: 초기화 컨테이너(Init Containers) 디버그하기
content_type: task
weight: 40
---
<!-- overview -->
@@ -0,0 +1,159 @@
---
title: 파드 디버깅하기
content_type: task
weight: 10
---
<!-- overview -->
이 가이드는 쿠버네티스에 배포되었지만 제대로 동작하지 않는 애플리케이션을 디버깅하는 방법을 소개한다.
이 가이드는 클러스터 디버깅에 대한 것은 아니다.
클러스터 디버깅에 대해서는 [이 가이드](/ko/docs/tasks/debug/debug-cluster/)를 참고한다.
<!-- body -->
## 문제 진단하기
트러블슈팅의 첫 단계는 문제를 파악하는 것이다.
무엇이 문제인가? 파드인가, 레플리케이션 컨트롤러인가, 서비스인가?
* [파드 디버깅하기](#debugging-pods)
* [레플리케이션컨트롤러 디버깅하기](#debugging-replication-controllers)
* [서비스 디버깅하기](#debugging-services)
### 파드 디버깅하기 {#debugging-pods}
파드 디버깅의 첫 번째 단계는 파드를 살펴 보는 것이다. 다음의 명령어를 사용하여 파드의 현재 상태와 최근 이벤트를 점검한다.
```shell
kubectl describe pods ${POD_NAME}
```
파드 내부 컨테이너의 상태를 확인한다. 모두 `Running` 상태인가? 최근에 재시작 되었는가?
파드의 상태에 따라 디버깅을 계속한다.
#### 파드가 계속 pending 상태인 경우
파드가 `Pending` 상태로 멈춰 있는 경우는, 노드에 스케줄 될 수 없음을 의미한다.
일반적으로 이것은 어떤 유형의 리소스가 부족하거나 스케줄링을 방해하는 다른 요인 때문이다.
상단의 `kubectl describe ...` 명령의 결과를 확인하자.
파드를 스케줄 할 수 없는 사유에 대한 스케줄러의 메세지가 있을 것이다. 다음과 같은 사유가 있을 수 있다.
* **리소스가 부족한 경우**: 사용자 클러스터의 CPU 나 메모리가 고갈되었을 수 있다.
이러한 경우, 파드를 삭제하거나, 리소스 요청을 조정하거나, 클러스터에 노드를 추가해야 한다.
[컴퓨트 자원 문서](/ko/docs/concepts/configuration/manage-resources-containers/)에서 더 많은 정보를 확인한다.
* **`hostPort`를 사용하고 있는 경우**: 파드를 `hostPort`에 바인딩할 때, 파드가 스케줄링될 수 있는 장소 수 제한이 존재한다.
대부분의 경우 `hostPort`는 불필요하므로, 파드를 노출하기 위해서는 서비스(Service) 오브젝트 사용을 고려해 본다.
`hostPort`가 꼭 필요하다면 클러스터의 노드 수 만큼만 파드를 스케줄링할 수 있다.
#### 파드가 계속 waiting 상태인 경우
파드가 `Waiting` 상태에서 멈춘 경우는, 파드가 워커 노드에 스케줄링되었지만 해당 노드에서 실행될 수 없음을 의미한다.
다시 말하지만, `kubectl describe ...` 명령은 유용한 정보를 제공한다. 파드가 `Waiting` 상태에서 멈추는 가장 흔한 원인은 이미지 풀링(pulling)에 실패했기 때문이다. 다음의 3가지 사항을 확인한다.
* 이미지 이름이 올바른지 확인한다.
* 해당 이미지를 저장소에 푸시하였는가?
* 이미지가 풀 될 수 있는지 확인하기 위해 수동으로 이미지를 풀 해본다.
예를 들어, PC에서 도커를 사용하는 경우, `docker pull <image>` 명령을 실행한다.
#### 파드가 손상(crashing)되었거나 양호하지 않을(unhealthy) 경우
일단 사용자의 파드가 스케줄 되면, [구동중인 파드 디버그하기](/ko/docs/tasks/debug/debug-application/debug-running-pod/)에
있는 방법을 사용하여 디버깅을 할 수 있다.
#### 파드가 running 상태이지만 해야 할 일을 하고 있지 않은 경우
파드가 예상과 다르게 동작 중이라면, 파드 상세(예: 로컬 머신에 있는 `mypod.yaml` 파일)에 에러가 있었는데
파드 생성 시에 에러가 조용히 지나쳐진 경우일 수 있다.
종종 파드 상세의 들여쓰기가 잘못되었거나,
키 이름에 오타가 있어서 해당 키가 무시되는 일이 있을 수 있다.
예를 들어, `command``commnd`로 잘못 기재했다면
해당 파드는 생성은 되지만 명시한 명령줄을 실행하지 않을 것이다.
가장 먼저 해야 할 일은 파드를 삭제한 다음, `--validate` 옵션을 사용하여 다시 만들어 보는 것이다.
예를 들어, `kubectl apply --validate -f mypod.yaml` 를 실행한다.
`command``commnd`로 잘못 기재했다면 다음과 같은 에러가 발생할 것이다.
```shell
I0805 10:43:25.129850 46757 schema.go:126] unknown field: commnd
I0805 10:43:25.129973 46757 schema.go:129] this may be a false alarm, see https://github.com/kubernetes/kubernetes/issues/6842
pods/mypod
```
<!-- TODO: Now that #11914 is merged, this advice may need to be updated -->
다음으로 확인할 것은 apiserver를 통해 확인한 파드 상세가
사용자가 의도한 파드 상세(예: 로컬 머신에 있는 yaml 파일)와 일치하는지 여부이다.
예를 들어, `kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml` 를 실행한 다음,
원본 파드 상세(`mypod.yaml`)와 apiserver를 통해 확인한 파드 상세(`mypod-on-apiserver.yaml`)를 수동으로 비교한다.
보통 원본 버전에는 없지만 "apiserver" 버전에는 있는 줄들이 존재한다.
이는 예상대로이다.
하지만, 원본 버전에는 있지만 "apiserver" 버전에는 없는 줄들이 있다면,
이는 원본 파드 상세에 문제가 있을 수도 있음을 의미한다.
## 레플리케이션컨트롤러 디버깅하기 {#debugging-replication-controllers}
레플리케이션컨트롤러의 경우에는 매우 직관적이다. 파드 생성이 가능하거나 또는 불가능한 경우 둘 뿐이다.
레플리케이션컨트롤러가 파드를 생성할 수 없다면, [위의 지침](#debugging-pods)을 참고하여 파드를 디버깅한다.
사용자는 `kubectl describe rc ${CONTROLLER_NAME}` 을 사용하여
레플리케이션 컨트롤러와 관련된 이벤트를 검사할 수도 있다.
### 서비스 디버깅하기 {#debugging-services}
서비스는 파드 집합에 대한 로드 밸런싱 기능을 제공한다. 일반적인 몇몇 문제들 때문에 서비스가 제대로 동작하지 않을 수 있다.
다음 지침을 이용하여 서비스 문제를 디버깅할 수 있다.
먼저, 서비스를 위한 엔드포인트가 존재하는지 확인한다. 모든 서비스 오브젝트에 대해, apiserver는 `endpoints` 리소스를 생성하고 사용 가능한(available) 상태로 만든다.
다음 명령을 사용하여 이 리소스를 볼 수 있다.
```shell
kubectl get endpoints ${SERVICE_NAME}
```
엔드포인트의 수가 해당 서비스에 속하는 파드의 수와 일치하는지 확인한다.
예를 들어, 서비스가 레플리카 3개인 nginx 컨테이너를 위한 것이라면,
서비스의 엔드포인트 항목에서 서로 다른 3개의 IP 주소가 확인되어야 한다.
#### 서비스에 엔드포인트가 없는 경우
엔드포인트가 없는 상태라면, 서비스가 사용 중인 레이블을 이용하여 파드 목록을 조회해 본다.
다음과 같은 레이블을 갖는 서비스를 가정한다.
```yaml
...
spec:
- selector:
name: nginx
type: frontend
```
다음의 명령을 사용하여,
```shell
kubectl get pods --selector=name=nginx,type=frontend
```
이 셀렉터에 매치되는 파드 목록을 조회할 수 있다. 서비스에 속할 것으로 예상하는 파드가 모두 조회 결과에 있는지 확인한다.
파드의 `containerPort`가 서비스의 `targetPort`와 일치하는지 확인한다.
#### 네트워크 트래픽이 포워드되지 않는 경우
[서비스 디버깅하기](/docs/tasks/debug/debug-application/debug-service/)에서 더 많은 정보를 확인한다.
## {{% heading "whatsnext" %}}
위의 방법 중 어떤 것으로도 문제가 해결되지 않는다면,
[서비스 디버깅하기 문서](/docs/tasks/debug/debug-application/debug-service/)를 참조하여
`서비스`가 실행 중인지, 서비스에 `엔드포인트`가 있는지, `파드`가 실제로 서빙 중인지 확인한다.
예를 들어, DNS가 실행 중이고, iptables 규칙이 설정되어 있고, kube-proxy가 정상적으로 동작하는 것으로 보이는 상황이라면,
위와 같은 사항을 확인해 볼 수 있다.
[트러블슈팅 문서](/ko/docs/tasks/debug/)에서 더 많은 정보를 볼 수도 있다.
@@ -0,0 +1,638 @@
---
title: 동작 중인 파드 디버그
content_type: task
---
<!-- overview -->
이 페이지는 노드에서 동작 중인(혹은 크래시된) 파드를 디버그하는 방법에 대해 설명한다.
## {{% heading "prerequisites" %}}
* 여러분의 {{< glossary_tooltip text="파드" term_id="pod" >}}는 이미 스케줄링 되어
동작하고 있을 것이다. 만약 파드가 아직 동작중이지 않다면, [애플리케이션
트러블슈팅](/ko/docs/tasks/debug/debug-application/)을 참고한다.
* 일부 고급 디버깅 과정에서는 해당 파드가 어떤 노드에서 동작하고 있는지
알아야 하고, 해당 노드에서 쉘 명령어를 실행시킬 수 있어야 한다.
`kubectl`을 사용하는 일반적인 디버깅 과정에서는 이러한 접근 권한이 필요하지 않다.
## `kubectl describe pod` 명령으로 파드 상세사항 가져오기
이 예제에서는 앞의 예제와 비슷하게 두 개의 파드를 생성하기 위해 디플로이먼트를 사용할 것이다.
{{< codenew file="application/nginx-with-request.yaml" >}}
다음 명령을 실행하여 디플로이먼트를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/application/nginx-with-request.yaml
```
```none
deployment.apps/nginx-deployment created
```
다음 명령을 실행하여 파드 상태를 확인한다.
```shell
kubectl get pods
```
```none
NAME READY STATUS RESTARTS AGE
nginx-deployment-67d4bdd6f5-cx2nz 1/1 Running 0 13s
nginx-deployment-67d4bdd6f5-w6kd7 1/1 Running 0 13s
```
다음과 같이 `kubectl describe pod` 명령을 사용하여 각 파드에 대한 더 많은 정보를 가져올 수 있다.
```shell
kubectl describe pod nginx-deployment-67d4bdd6f5-w6kd7
```
```none
Name: nginx-deployment-67d4bdd6f5-w6kd7
Namespace: default
Priority: 0
Node: kube-worker-1/192.168.0.113
Start Time: Thu, 17 Feb 2022 16:51:01 -0500
Labels: app=nginx
pod-template-hash=67d4bdd6f5
Annotations: <none>
Status: Running
IP: 10.88.0.3
IPs:
IP: 10.88.0.3
IP: 2001:db8::1
Controlled By: ReplicaSet/nginx-deployment-67d4bdd6f5
Containers:
nginx:
Container ID: containerd://5403af59a2b46ee5a23fb0ae4b1e077f7ca5c5fb7af16e1ab21c00e0e616462a
Image: nginx
Image ID: docker.io/library/nginx@sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 17 Feb 2022 16:51:05 -0500
Ready: True
Restart Count: 0
Limits:
cpu: 500m
memory: 128Mi
Requests:
cpu: 500m
memory: 128Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bgsgp (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-bgsgp:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 34s default-scheduler Successfully assigned default/nginx-deployment-67d4bdd6f5-w6kd7 to kube-worker-1
Normal Pulling 31s kubelet Pulling image "nginx"
Normal Pulled 30s kubelet Successfully pulled image "nginx" in 1.146417389s
Normal Created 30s kubelet Created container nginx
Normal Started 30s kubelet Started container nginx
```
위 예시에서 컨테이너와 파드에 대한 구성 정보(레이블, 리소스 요구사항 등) 및 상태 정보(상태(state), 준비성(readiness), 재시작 횟수, 이벤트 등)를 볼 수 있다.
컨테이너의 상태(state)값은 Waiting, Running, 또는 Terminated 중 하나이다. 각 상태에 따라, 추가 정보가 제공될 것이다. 위 예시에서 Running 상태의 컨테이너에 대해서는 컨테이너의 시작 시각을 시스템이 표시해 주는 것을 볼 수 있다.
Ready 값은 컨테이너의 마지막 준비성 프로브(readiness probe) 통과 여부를 알려 준다. (위 예시에서는 컨테이너에 준비성 프로브가 설정되어 있지 않다. 컨테이너에 준비성 프로브가 설정되어 있지 않으면, 컨테이너는 준비(ready) 상태로 간주된다.)
'재시작 카운트'는 컨테이너가 재시작된 횟수를 보여 준다. 이 정보는 재시작 정책이 'always'로 설정된 컨테이너의 반복적인 강제 종료를 알아차리는 데에 유용하다.
위 예시에서 파드와 연관된 유일한 컨디션(Condition)은 True 또는 False 값을 갖는 Ready 컨디션이며, 이 값이 True라는 것은 파드가 요청을 처리할 수 있으며 모든 동일한 서비스를 묶는 로드 밸런싱 풀에 추가되어야 함을 의미한다.
마지막으로, 파드와 관련된 최근 이벤트 로그가 표시된다. 시스템은 동일한 여러 이벤트를 처음/마지막 발생 시간 및 발생 횟수만 압축적으로 표시한다. "From"은 이벤트 로그를 발생하는 구성 요소를 가리키고, "SubobjectPath"는 참조되는 개체(예: 파드 내 컨테이너)를 나타내며, "Reason" 및 "Message"는 발생한 상황을 알려 준다.
## 예시: Pending 상태의 파드 디버깅하기
이벤트를 사용하여 감지할 수 있는 일반적인 시나리오는 노드에 할당될 수 없는 파드를 생성하는 경우이다. 예를 들어 파드가 노드에 사용 가능한 리소스보다 더 많은 리소스를 요청하거나, 또는 어떤 노드에도 해당되지 않는 레이블 셀렉터를 명시했을 수 있다. 예를 들어 4개 노드로 구성되며 각 (가상) 머신에 1 CPU가 있는 클러스터가 있는 상황에서, 위 예시 대신 2 레플리카가 아니라 5 레플리카를, 500 밀리코어가 아니라 600 밀리코어를 요청하는 디플로이먼트를 배포했다고 해 보자. 이러한 경우 5개의 파드 중 하나는 스케줄링될 수 없을 것이다. (각 노드에는 fluentd, skydns 등의 클러스터 애드온도 실행되고 있으므로, 만약 1000 밀리코어를 요청했다면 파드가 하나도 스케줄될 수 없었을 것이다.)
```shell
kubectl get pods
```
```none
NAME READY STATUS RESTARTS AGE
nginx-deployment-1006230814-6winp 1/1 Running 0 7m
nginx-deployment-1006230814-fmgu3 1/1 Running 0 7m
nginx-deployment-1370807587-6ekbw 1/1 Running 0 1m
nginx-deployment-1370807587-fg172 0/1 Pending 0 1m
nginx-deployment-1370807587-fz9sd 0/1 Pending 0 1m
```
nginx-deployment-1370807587-fz9sd 파드가 왜 실행되지 않는지를 알아 보려면, pending 상태의 파드에 대해 `kubectl describe pod` 명령을 실행하고 이벤트(event) 항목을 확인해 볼 수 있다.
```shell
kubectl describe pod nginx-deployment-1370807587-fz9sd
```
```none
Name: nginx-deployment-1370807587-fz9sd
Namespace: default
Node: /
Labels: app=nginx,pod-template-hash=1370807587
Status: Pending
IP:
Controllers: ReplicaSet/nginx-deployment-1370807587
Containers:
nginx:
Image: nginx
Port: 80/TCP
QoS Tier:
memory: Guaranteed
cpu: Guaranteed
Limits:
cpu: 1
memory: 128Mi
Requests:
cpu: 1
memory: 128Mi
Environment Variables:
Volumes:
default-token-4bcbi:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4bcbi
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 48s 7 {default-scheduler } Warning FailedScheduling pod (nginx-deployment-1370807587-fz9sd) failed to fit in any node
fit failure on node (kubernetes-node-6ta5): Node didn't have enough resource: CPU, requested: 1000, used: 1420, capacity: 2000
fit failure on node (kubernetes-node-wul5): Node didn't have enough resource: CPU, requested: 1000, used: 1100, capacity: 2000
```
여기서 스케줄러가 기록한 이벤트를 통해, 파드가 `FailedScheduling` 사유로 인해 스케줄링되지 않았음을 알 수 있다(다른 이유도 있을 수 있음). 이 메시지를 통해 어떤 노드에도 이 파드를 실행하기 위한 충분한 리소스가 없었음을 알 수 있다.
이 상황을 바로잡으려면, `kubectl scale` 명령으로 디플로이먼트의 레플리카를 4 이하로 줄일 수 있다. (또는 한 파드를 pending 상태로 두어도 되며, 이렇게 해도 문제는 없다.)
`kubectl describe pod` 출력의 마지막에 있는 것과 같은 이벤트는 etcd에 기록되어 보존되며 클러스터에 어떤 일이 일어나고 있는지에 대한 높은 차원의 정보를 제공한다. 모든 이벤트의 목록을 보려면 다음 명령을 실행한다.
```shell
kubectl get events
```
그런데 이벤트는 네임스페이스 스코프 객체라는 것을 기억해야 한다. 즉 네임스페이스 스코프 객체에 대한 이벤트(예: `my-namespace` 네임스페이스의 파드에 어떤 일이 발생했는지)가 궁금하다면, 다음과 같이 커맨드에 네임스페이스를 명시해야 한다.
```shell
kubectl get events --namespace=my-namespace
```
모든 네임스페이스에 대한 이벤트를 보려면, `--all-namespaces` 인자를 사용할 수 있다.
`kubectl describe pod` 명령 외에도, `kubectl get pod` 이상의 정보를 얻는 다른 방법은 `kubectl get pod` 명령에 출력 형식 플래그 `-o yaml` 인자를 추가하는 것이다. 이렇게 하면 `kubectl describe pod` 명령보다 더 많은 정보, 원천적으로는 시스템이 파드에 대해 알고 있는 모든 정보를 YAML 형식으로 볼 수 있다. 여기서 어노테이션(레이블 제한이 없는 키-밸류 메타데이터이며, 쿠버네티스 시스템 구성 요소가 내부적으로 사용함), 재시작 정책, 포트, 볼륨과 같은 정보를 볼 수 있을 것이다.
```shell
kubectl get pod nginx-deployment-1006230814-6winp -o yaml
```
```yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2022-02-17T21:51:01Z"
generateName: nginx-deployment-67d4bdd6f5-
labels:
app: nginx
pod-template-hash: 67d4bdd6f5
name: nginx-deployment-67d4bdd6f5-w6kd7
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: nginx-deployment-67d4bdd6f5
uid: 7d41dfd4-84c0-4be4-88ab-cedbe626ad82
resourceVersion: "1364"
uid: a6501da1-0447-4262-98eb-c03d4002222e
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 500m
memory: 128Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-bgsgp
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: kube-worker-1
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-bgsgp
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2022-02-17T21:51:01Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2022-02-17T21:51:06Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2022-02-17T21:51:06Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2022-02-17T21:51:01Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://5403af59a2b46ee5a23fb0ae4b1e077f7ca5c5fb7af16e1ab21c00e0e616462a
image: docker.io/library/nginx:latest
imageID: docker.io/library/nginx@sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
lastState: {}
name: nginx
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2022-02-17T21:51:05Z"
hostIP: 192.168.0.113
phase: Running
podIP: 10.88.0.3
podIPs:
- ip: 10.88.0.3
- ip: 2001:db8::1
qosClass: Guaranteed
startTime: "2022-02-17T21:51:01Z"
```
## 파드의 로그 확인하기 {#examine-pod-logs}
먼저, 확인하고자 하는 컨테이너의 로그를 확인한다.
```shell
kubectl logs ${POD_NAME} ${CONTAINER_NAME}
```
만약 컨테이너가 이전에 크래시 되었다면, 다음의 명령을 통해 컨테이너의 크래시 로그를 살펴볼 수 있다.
```shell
kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
```
## exec를 통해 컨테이너 디버깅하기 {#container-exec}
만약 {{< glossary_tooltip text="컨테이너 이미지" term_id="image" >}}에
디버깅 도구가 포함되어 있다면, `kubectl exec`을 통해 특정 컨테이너에서 해당 명령들을
실행할 수 있다. (리눅스나 윈도우 OS를 기반으로 만들어진 이미지에는 대부분 디버깅 도구를 포함하고
있다.)
```shell
kubectl exec ${POD_NAME} -c ${CONTAINER_NAME} -- ${CMD} ${ARG1} ${ARG2} ... ${ARGN}
```
{{< note >}}
`-c ${CONTAINER_NAME}` 인자는 선택적이다. 만약 하나의 컨테이너만 포함된 파드라면 해당 옵션을 생략할 수 있다.
{{< /note >}}
예를 들어, 동작 중인 카산드라 파드의 로그를 살펴보기 위해서는 다음과 같은 명령을 실행할 수 있다.
```shell
kubectl exec cassandra -- cat /var/log/cassandra/system.log
```
`kubectl exec``-i``-t` 옵션을 사용해서 터미널에서 접근할 수 있는 쉘을 실행시킬 수도 있다.
예를 들면 다음과 같다.
```shell
kubectl exec -it cassandra -- sh
```
더욱 상세한 내용은
[동작중인 컨테이너의 쉘에 접근하기](/ko/docs/tasks/debug/debug-application/get-shell-running-container/)를 참고한다.
## 임시(ephemeral) 디버그 컨테이너를 사용해서 디버깅하기 {#ephemeral-container}
{{< feature-state state="beta" for_k8s_version="v1.23" >}}
컨테이너가 크래시 됐거나
[distroless 이미지](https://github.com/GoogleContainerTools/distroless)처럼
컨테이너 이미지에 디버깅 도구를 포함하고 있지 않아 `kubectl exec`로는 충분하지 않은 경우에는
{{< glossary_tooltip text="임시(Ephemeral) 컨테이너" term_id="ephemeral-container" >}}를 사용하는 것이
인터랙티브한 트러블슈팅에 유용하다.
### 임시 컨테이너를 사용한 디버깅 예시 {#ephemeral-container-example}
`kubectl debug` 명령어를 사용해서 동작 중인 파드에 임시 컨테이너를 추가할 수 있다.
먼저, 다음과 같이 파드를 추가한다.
```shell
kubectl run ephemeral-demo --image=k8s.gcr.io/pause:3.1 --restart=Never
```
이 섹션의 예시에서는 디버깅 도구가 포함되지 않은 이미지의 사례를 보여드리기 위해
`pause` 컨테이너 이미지를 사용했는데, 이 대신 어떠한 이미지를 사용해도
될 것이다.
만약 `kubectl exec`을 통해 쉘을 생성하려 한다면 다음과 같은 에러를
확인할 수 있을 텐데, 그 이유는 이 이미지에 쉘이 존재하지 않기 때문이다.
```shell
kubectl exec -it ephemeral-demo -- sh
```
```
OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"sh\": executable file not found in $PATH": unknown
```
이 명령어 대신 `kubectl debug`을 사용해서 디버깅 컨테이너를 생성할 수 있다.
만약 `-i`/`--interactive` 인자를 사용한다면, `kubectl`은 임시
컨테이너의 콘솔에 자동으로 연결할 것이다.
```shell
kubectl debug -it ephemeral-demo --image=busybox --target=ephemeral-demo
```
```
Defaulting debug container name to debugger-8xzrl.
If you don't see a command prompt, try pressing enter.
/ #
```
이 명령어는 새로운 busybox 컨테이너를 추가하고 해당 컨테이너로 연결한다. `--target`
파라미터를 사용하면 다른 컨테이너의 프로세스 네임스페이스를 대상으로 하게 된다. 여기서는
이 옵션이 꼭 필요한데, `kubectl run`이 생성하는 파드에 대해
[프로세스 네임스페이스 공유](/docs/tasks/configure-pod-container/share-process-namespace/)를
활성화하지 않기 때문이다.
{{< note >}}
`--target` 파라미터는 사용 중인
{{< glossary_tooltip text="컨테이너 런타임" term_id="container-runtime" >}}에서
지원해야지만 사용할 수 있다. 만일 지원되지 않는다면,
임시 컨테이너가 시작되지 않을 수 있거나 독립적인 프로세스
네임스페이스를 가지고 시작될 수 있다.
{{< /note >}}
`kubectl describe` 명령을 사용하면 새롭게 생성된 임시 컨테이너의 상태를 확인할 수 있다.
```shell
kubectl describe pod ephemeral-demo
```
```
...
Ephemeral Containers:
debugger-8xzrl:
Container ID: docker://b888f9adfd15bd5739fefaa39e1df4dd3c617b9902082b1cfdc29c4028ffb2eb
Image: busybox
Image ID: docker-pullable://busybox@sha256:1828edd60c5efd34b2bf5dd3282ec0cc04d47b2ff9caa0b6d4f07a21d1c08084
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 12 Feb 2020 14:25:42 +0100
Ready: False
Restart Count: 0
Environment: <none>
Mounts: <none>
...
```
디버깅이 다 끝나면 `kubectl delete`을 통해 파드를 제거할 수 있다.
```shell
kubectl delete pod ephemeral-demo
```
## 파드의 복제본을 이용해서 디버깅하기
때때로 파드의 설정 옵션에 따라 특정 상황에서 트러블슈팅을 하기가 어려울 수 있다.
예를 들어, 만일 여러분의 컨테이너 이미지가 쉘을 포함하고 있지 않거나, 여러분의
애플리케이션이 컨테이너 시작에서 크래시가 발생한다면 `kubectl exec`을 이용해서
컨테이너를 트러블슈팅할 수 없을 수 있다. 이러한 상황에서는 `kubectl debug`을 사용해서
파드의 복제본을 디버깅을 위한 추가적인 설정 옵션과 함께 생성할 수 있다.
### 새 컨테이너와 함께 파드의 복제본 생성하기
만일 여러분의 애플리케이션이 동작은 하고 있지만 예상과는 다르게 동작하는 경우,
파드의 복제본에 새로운 컨테이너를 추가함으로써 추가적인 트러블슈팅 도구들을
파드에 함께 추가할 수 있다.
가령, 여러분의 애플리케이션 컨테이너 이미지는 `busybox`를 기반으로 하고 있는데
여러분은 `busybox`에는 없는 디버깅 도구를 필요로 한다고 가정해 보자. 이러한
시나리오는 `kubectl run` 명령을 통해 시뮬레이션 해볼 수 있다.
```shell
kubectl run myapp --image=busybox --restart=Never -- sleep 1d
```
다음의 명령을 실행시켜 디버깅을 위한 새로운 우분투 컨테이너와 함께 `myapp-debug`이란
이름의 `myapp` 컨테이너 복제본을 생성할 수 있다.
```shell
kubectl debug myapp -it --image=ubuntu --share-processes --copy-to=myapp-debug
```
```
Defaulting debug container name to debugger-w7xmf.
If you don't see a command prompt, try pressing enter.
root@myapp-debug:/#
```
{{< note >}}
* 만일 여러분이 새로 생성되는 컨테이너의 이름을 `--container` 플래그와 함께 지정하지 않는다면,
`kubectl debug`는 자동으로 새로운 컨테이너 이름을 생성한다.
* `-i` 플래그를 사용하면 `kubectl debug` 명령이 새로운 컨테이너에 기본적으로 연결되게 된다.
이러한 동작은 `--attach=false`을 지정하여 방지할 수 있다. 만일 여러분의 세션이
연결이 끊어진다면 `kubectl attach`를 사용해서 다시 연결할 수 있다.
* `--share-processes` 옵션은 이 파드에 있는 컨테이너가 해당 파드에 속한 다른 컨테이너의
프로세스를 볼 수 있도록 한다. 이 옵션이 어떻게 동작하는지에 대해 더 알아보기 위해서는
다음의 [파드의 컨테이너 간 프로세스 네임스페이스 공유](
/docs/tasks/configure-pod-container/share-process-namespace/)를 참고하라.
{{< /note >}}
사용이 모두 끝나면, 디버깅에 사용된 파드를 잊지 말고 정리한다.
```shell
kubectl delete pod myapp myapp-debug
```
### 명령어를 변경하며 파드의 복제본 생성하기
때때로 컨테이너의 명령어를 변경하는 것이 유용한 경우가 있는데, 예를 들면 디버그 플래그를 추가하기
위해서나 애플리케이션이 크래시 되는 경우이다.
다음의 `kubectl run` 명령을 통해 즉각적으로 크래시가 발생하는 애플리케이션의
사례를 시뮬레이션해 볼 수 있다.
```
kubectl run --image=busybox myapp -- false
```
`kubectl describe pod myapp` 명령을 통해 이 컨테이너에 크래시가 발생하고 있음을 확인할 수 있다.
```
Containers:
myapp:
Image: busybox
...
Args:
false
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Error
Exit Code: 1
```
이러한 경우에 `kubectl debug`을 통해 명령어를 지정함으로써 해당 파드의
복제본을 인터랙티브 쉘로 생성할 수 있다.
```
kubectl debug myapp -it --copy-to=myapp-debug --container=myapp -- sh
```
```
If you don't see a command prompt, try pressing enter.
/ #
```
이제 인터랙티브 쉘에 접근할 수 있으니 파일 시스템 경로를 확인하거나
동작 중인 컨테이너의 명령어를 직접 확인하는 등의 작업이 가능하다.
{{< note >}}
* 특정 컨테이너의 명령어를 변경하기 위해서는 `--container` 옵션을 통해 해당 컨테이너의
이름을 지정해야만 한다. 이름을 지정하지 않는다면 `kubectl debug`은 이전에 지정한 명령어를
그대로 사용해서 컨테이너를 생성할 것이다.
* 기본적으로 `-i` 플래그는 `kubectl debug` 명령이 컨테이너에 바로 연결되도록 한다.
이러한 동작을 방지하기 위해서는 `--attach=false` 옵션을 지정할 수 있다. 만약 여러분이 세션이
종료된다면 `kubectl attach` 명령을 통해 다시 연결할 수 있다.
{{< /note >}}
사용이 모두 끝나면, 디버깅에 사용된 파드들을 잊지 말고 정리한다.
```shell
kubectl delete pod myapp myapp-debug
```
### 컨테이너 이미지를 변경하며 파드의 복제본 생성하기
특정한 경우에 여러분은 제대로 동작하지 않는 파드의 이미지를
기존 프로덕션 컨테이너 이미지에서 디버깅 빌드나 추가적인 도구를 포함한
이미지로 변경하고 싶을 수 있다.
이 사례를 보여주기 위해 `kubectl run` 명령을 통해 파드를 생성하였다.
```
kubectl run myapp --image=busybox --restart=Never -- sleep 1d
```
여기서는 `kubectl debug` 명령을 통해 해당 컨테이너 이미지를 `ubuntu`로 변경하며
복제본을 생성하였다.
```
kubectl debug myapp --copy-to=myapp-debug --set-image=*=ubuntu
```
`--set-image`의 문법은 `kubectl set image`와 동일하게 `container_name=image`
형식의 문법을 사용한다. `*=ubuntu`라는 의미는 모든 컨테이너의 이미지를 `ubuntu`
변경하겠다는 의미이다.
사용이 모두 끝나면, 디버깅에 사용된 파드를 잊지 말고 정리한다.
```shell
kubectl delete pod myapp myapp-debug
```
## 노드의 쉘을 사용해서 디버깅하기 {#node-shell-session}
만약 위의 어떠한 방법도 사용할 수 없다면, 파드가 현재 동작 중인 노드를 찾아
호스트의 네임스페이스로 동작하는 특권 파드를 생성할 수 있다.
다음 `kubectl debug` 명령을 통해 해당 노드에서 인터랙티브한 쉘을 생성할 수 있다.
```shell
kubectl debug node/mynode -it --image=ubuntu
```
```
Creating debugging pod node-debugger-mynode-pdx84 with container debugger on node mynode.
If you don't see a command prompt, try pressing enter.
root@ek8s:/#
```
노드에서 디버깅 세션을 생성할 때 유의해야 할 점은 다음과 같다.
* `kubectl debug`는 노드의 이름에 기반해 새로운 파드의 이름을
자동으로 생성한다.
* 컨테이너는 호스트 네임스페이스(IPC, 네트워크, PID 네임스페이스)에서 동작한다.
* 노드의 루트 파일시스템은 `/host`에 마운트된다.
사용이 모두 끝나면, 디버깅에 사용된 파드를 잊지 말고 정리한다.
```shell
kubectl delete pod node-debugger-mynode-pdx84
```
@@ -9,6 +9,7 @@
title: 스테이트풀셋 디버깅하기
content_type: task
weight: 30
---
<!-- overview -->
@@ -34,10 +35,8 @@ kubectl get pods -l app=myapp
파드들을 발견하였다면, 이러한 파드들을 어떻게 다루는지 알아보기 위해
[스테이트풀셋 파드 삭제하기](/ko/docs/tasks/run-application/delete-stateful-set/)를 참고하길 바란다.
스테이트풀셋에 포함된 개별 파드들을 디버깅하기 위해서는
[파드 디버그하기](/ko/docs/tasks/debug-application-cluster/debug-pod-replication-controller/) 가이드를 참고하길 바란다.
[파드 디버그하기](/ko/docs/tasks/debug/debug-application/debug-pods/) 가이드를 참고하길 바란다.
## {{% heading "whatsnext" %}}
[초기화 컨테이너(Init container) 디버그하기](/ko/docs/tasks/debug-application-cluster/debug-init-containers/)를 참고길 바란다.
[초기화 컨테이너(Init container) 디버그하기](/ko/docs/tasks/debug/debug-application/debug-init-containers/)를 참고길 바란다.
@@ -75,6 +75,12 @@ content_type: task
kubectl get pod termination-demo -o go-template="{{range .status.containerStatuses}}{{.lastState.terminated.message}}{{end}}"
여러 컨테이너를 포함하는 파드의 경우, Go 템플릿을 사용하여 컨테이너 이름도 출력할 수 있다. 이렇게 하여, 어떤 컨테이너가 실패하는지 찾을 수 있다.
```shell
kubectl get pod multi-container-pod -o go-template='{{range .status.containerStatuses}}{{printf "%s:\n%s\n\n" .name .lastState.terminated.message}}{{end}}'
```
## 종료 메시지 사용자 정의하기
쿠버네티스는 컨테이너의 `terminationMessagePath` 필드에 지정된
@@ -154,4 +154,4 @@ kubectl exec -i -t my-pod --container main-app -- /bin/bash
## {{% heading "whatsnext" %}}
* [kubectl exec](/docs/reference/generated/kubectl/kubectl-commands/#exec)를 참고한다.
* [kubectl exec](/docs/reference/generated/kubectl/kubectl-commands/#exec)를 참고한다.
@@ -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 >}}
@@ -1,6 +1,9 @@
---
content_type: concept
title: 리소스 모니터링 도구
weight: 15
---
<!-- overview -->
@@ -31,16 +34,18 @@ title: 리소스 모니터링 도구
[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`에서
제공된다.
metrics-server는 클러스터 상의 모든 노드를 발견하고
각 노드의 [kubelet](/docs/reference/command-line-tools-reference/kubelet/)에
CPU와 메모리 사용량을 질의한다.
Kubelet은 쿠버네티스 마스터와 노드 간의 다리 역할을 하면서
머신에서 구동되는 파드와 컨테이너를 관리한다.
Kubelet은 각각의 파드를 해당하는 컨테이너에 매치시키고
컨테이너 런타임 인터페이스를 통해
컨테이너 런타임에서 개별 컨테이너의 사용량 통계를 가져온다.
Kubelet은 이 정보를 레거시 도커와의 통합을 위해 kubelet에 통합된 cAdvisor를 통해 가져온다.
그 다음으로 취합된 파드 리소스 사용량 통계를 metric-server 리소스 메트릭 API를 통해 노출한다.
이 API는 kubelet의 인증이 필요한 읽기 전용 포트 상의
`/metrics/resource/v1beta1`에서 제공된다.
## 완전한 메트릭 파이프라인
@@ -51,5 +56,17 @@ kubelet의 인증이 필요한 읽기 전용 포트 상의 `/metrics/resource/v1
`custom.metrics.k8s.io``external.metrics.k8s.io` API를 구현한 어댑터를 통해
노출한다.
CNCF 프로젝트인, [프로메테우스](https://prometheus.io)는 기본적으로 쿠버네티스, 노드, 프로메테우스 자체를 모니터링할 수 있다.
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/)
@@ -114,5 +114,5 @@ args: ["-c", "while true; do echo hello; sleep 10;done"]
* [파드와 컨테이너를 구성하는 방법](/ko/docs/tasks/)에 대해 더 알아본다.
* [컨테이너 안에서 커맨드를 실행하는 방법](/ko/docs/tasks/debug-application-cluster/get-shell-running-container/)에 대해 더 알아본다.
* [컨테이너 안에서 커맨드를 실행하는 방법](/ko/docs/tasks/debug/debug-application/get-shell-running-container/)에 대해 더 알아본다.
* [컨테이너](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#container-v1-core)를 확인한다.
@@ -91,6 +91,6 @@ kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'
## {{% heading "whatsnext" %}}
[스테이트풀셋 디버깅하기](/ko/docs/tasks/debug-application-cluster/debug-stateful-set/)에 대해 더 알아보기.
[스테이트풀셋 디버깅하기](/ko/docs/tasks/debug/debug-application/debug-statefulset/)에 대해 더 알아보기.
@@ -90,7 +90,7 @@ HorizontalPodAutoscaler를 사용하는 일반적인 방법은
`custom.metrics.k8s.io`, 또는 `external.metrics.k8s.io`)로부터 메트릭을 가져오도록 설정하는 것이다.
`metrics.k8s.io` API는 보통 메트릭 서버(Metrics Server)라는 애드온에 의해 제공되며,
Metrics Server는 별도로 실행해야 한다. 자원 메트릭에 대한 추가 정보는
[Metrics Server](/ko/docs/tasks/debug-application-cluster/resource-metrics-pipeline/#메트릭-서버)를 참고한다.
[Metrics Server](/ko/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/#metrics-server)를 참고한다.
[메트릭 API를 위한 지원](#메트릭-api를-위한-지원)에서 위의 API들에 대한 안정성 보장 및 지원 상태를
확인할 수 있다.
@@ -350,7 +350,7 @@ Events:
{{< note >}}
파드시큐리티폴리시는 쿠버네티스 v1.21에서 사용 중단되었으며, v1.25에서 제거될 예정이다.
더 자세한 내용은 [파드시큐리티폴리시](/ko/docs/concepts/policy/pod-security-policy/) 문서를 참고한다.
더 자세한 내용은 [파드시큐리티폴리시](/ko/docs/concepts/security/pod-security-policy/) 문서를 참고한다.
{{< /note >}}
만약 파드시큐리티폴리시 확장을 사용하면, 클러스터 단위로 AppArmor 제한을 적용할 수 있다.
@@ -93,7 +93,7 @@ cassandra ClusterIP None <none> 9042/TCP 45s
```
`cassandra` 서비스가 보이지 않는다면, 이와 다른 응답이라면 서비스 생성에 실패한 것이다. 일반적인 문제에 대한
[서비스 디버깅하기](/docs/tasks/debug-application-cluster/debug-service/)를
[서비스 디버깅하기](/docs/tasks/debug/debug-application/debug-service/)를
읽어보자.
## 카산드라 링을 생성하는 스테이트풀셋 이용하기
@@ -236,7 +236,7 @@ kubectl apply -k ./
## {{% heading "whatsnext" %}}
* [인트로스펙션과 디버깅](/docs/tasks/debug-application-cluster/debug-application-introspection/) 알아보자.
* [인트로스펙션과 디버깅](/ko/docs/tasks/debug/debug-application/debug-running-pod/) 알아보자.
* [](/ko/docs/concepts/workloads/controllers/job/)를 알아보자.
* [포트 포워딩](/ko/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)를 알아보자.
* 어떻게 [컨테이너에서 셸을 사용하는지](/ko/docs/tasks/debug-application-cluster/get-shell-running-container/)를 알아보자.
* 어떻게 [컨테이너에서 셸을 사용하는지](/ko/docs/tasks/debug/debug-application/get-shell-running-container/)를 알아보자.