레이블이 metrics-server인 게시물을 표시합니다. 모든 게시물 표시
레이블이 metrics-server인 게시물을 표시합니다. 모든 게시물 표시

k8s metrics-server pod resource issue

# k9s,ktop 등의 프로그램에서 에서 pod 리소스(cpu,mem) 사용량이 실제보다 2배로 보인다.
# kubectl(k) top pods 로 봐도 같다.
# 1개의 container 로 운영되는 pod 인데 이름이 없는 container 가 리소스를 똑같이 잡고 있어 pod 리소스에는 2배로 보인다.
kubectl top pods
kubectl top pods --containers

# 실제 metrics api 로 pod 정보를 요청해 보면 2개의 container 가 있고 하나는 이름이 없다.
kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/{네임스페이스}/pods/{파드} | jq .

# 네임스페이스 구분 없이 모든 pod 리소스가 위와 같이 2배로 보인다.
# metrics-server 를 재시작 해봤지만 변화가 없다.
kubectl rollout restart deployment metrics-server -n kube-system

# 현재 k8s 버전에 비해 metrics-server 버전이 낮은것 같다.
# k8s v1.26.4
# metrics-server k8s.gcr.io/metrics-server/metrics-server:v0.4.2
# 현재 최신 버전 0.7.2 으로 다시 설치해 보자.
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# metrics-server pod 에서 다음과 같은 tls 에러가 발생해
tls: failed to verify certificate: x509

# 다음 옵션을 추가하면 자동 재시작되고 정상 동작 한다.
kubectl edit deployment metrics-server -n kube-system
args:
  - --kubelet-insecure-tls

# metrics-server 가 최신버전으로 변경됐지만 문제는 여전하다.
# metrics-server 를 다음으로 삭제했는데 kubectl top 등이 동작한다.
kubectl delete -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# api 를 확인해보니 prometheus-adapter 서비스에서 제공하고 있다.
kubectl get apiservice v1beta1.metrics.k8s.io

# prometheus-adapter helm chart 를 보면 v1beta1.custom.metrics.k8s.io api 외 (kubectl top 에서 사용하는) /apis/metrics.k8s.io/v1beta1 (v1beta1.metrics.k8s.io) 를 서빙할 수 있다고 한다.
# 실제 prometheus-adapter configmap 을 보면 resourceRules 로 설정이 되어 있었다.
# 설명을 보면 https://github.com/helm/charts/tree/master/stable/metrics-server 의 기능을 제공한다고 하는데 chart 버전을 보면 deprecatd 된 0.3.6 을 참고하는것 같다.

# prometheus-adapter 가 선점하고 있는 v1beta1.metrics.k8s.io 서비스는 삭제한다.
# 참고로 apiservice 는 먼저 등록한쪽이 사용되고 나중에 등록된건 무시된다고 한다.
kubectl delete apiservice v1beta1.metrics.k8s.io

# 참고로 prometheus-adapter chart 는 자동 argocd 에서 자동 싱크되어 있어 v1beta1.metrics.k8s.io 를 선점하려고 해서 잠시 비활성화해야 했다.

# 다시 최신 metrics-server 를 설치하고 v1beta1.metrics.k8s.io 서비스를 확인하면 metrics-server 로 동작한다.
kubectl get apiservice v1beta1.metrics.k8s.io

# 이제 kubectl top pods --containers 에도 중복된 녀석이 보이지 않는다.

# 다시 prometheus-adapter 로 v1beta1.metrics.k8s.io 서빙하도록 설치하자.
# 원래 prometheus-adapter chart 에는 container_cpu_usage_seconds_total{container!=""} 로 빈이름의 container 는 제외 하는데 우리 클러스터에 적용시 이 조건이 누락되어 있있고 조건을 추가하니 container 리소스가 중복 취합 되지 않는다.

kubectl top node error

# 설치
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# node 를 조회하면 다음 에러가 발생한다.(kubectl top pods 는 정상동작)
kubectl top node
error: metrics not available yet

# kube-system > metrics-server deployment 가 제대로 동작하고 있지 않았다.
kubectl get deployment metrics-server -n kube-system
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
metrics-server   0/1     1            0           26h

# 이슈1 - 이미지 다운로드 실패
# 원인은 registry.k8s.io 에 대해서 방화벽 설정으로 이미지를 받아오지 못해서였다.
Pulling image "registry.k8s.io/metrics-server/metrics-server:v0.6.3"

# 우선 로컬에 이미지를 다운로드 받자.
docker pull registry.k8s.io/metrics-server/metrics-server:v0.6.3

# 이미지를 tar 로 만든다.
docker save -o metrics-server-v0.6.3.tar registry.k8s.io/metrics-server/metrics-server:v0.6.3

# 워커 노드에 tar 파일 전송
rsync -avz ./metrics-server-v0.6.3.tar ysoftman@worker1/home/ysoftman/
rsync -avz ./metrics-server-v0.6.3.tar ysoftman@worker2/home/ysoftman/
rsync -avz ./metrics-server-v0.6.3.tar ysoftman@worker3/home/ysoftman/

# 노드의 tar 이미지 파일을 로딩한다.
ssh ysoftman@worker1 "sudo docker load -i /home/ysoftman/metrics-server-v0.6.3.tar"
ssh ysoftman@worker2 "sudo docker load -i /home/ysoftman/metrics-server-v0.6.3.tar"
ssh ysoftman@worker3 "sudo docker load -i /home/ysoftman/metrics-server-v0.6.3.tar"

# metrics-server deployment 명세에 다음이 설정되어 있기 때문에
# imagePullPolicy: IfNotPresent
# pod 가 running 된다.

# 이슈2 - tls 비활성화
# metrics 로그를 보면 아래와같이 노드(kubelet)의 메트릭 수집시 실패한다고 나온다.
scraper.go:140] "Failed to scrape node" err="Get \"https://10.10.10.100:10250/metrics/resource\": read tcp 10.10.1.10:40752->10.10.10.100:10250: read: connection reset by peer" node="ysoftman-cpu1"

# metrics-server deployment> containers args 에 다음을 추가하면 위 에러는 발행하지 않고 정상 동작(scraping node ... scrap finished)한다.
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls  # 추가옵션
- --v=6 # 추가옵션 (Scraping node "node=xxxx" 노드 수집 성공 메시지 확인용)

# 이슈3 - apiservice 적용 안되는 이슈
# 아직도 error:metrics not available yet 이 발생한다.
# 찾아보니 kubectl 에서 top 커맨드 사용시 발생하는 에러 메시지였다.

# k8s api 로 node 메트릭을 다음과 같이 실행하면 결과가 나온다.
NODE_NAME="ysoftman-cpu1"
kubectl get --raw /api/v1/nodes/$NODE_NAME/proxy/metrics/resource | grep -i -E "node_cpu|node_mem"

# metrics api 에서 pods 응답은 나온다.
kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods | jq 

# 하지만 nodes 응답을 보면 items: [] 로 빈값으로 나온다.
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes | jq 

# metrics-server pod log 는 다음과 같이 노드로부터 정보를 받아 저장했다고 나온다.
round_trippers.go:553] GET https://10.10.10.10:10250/metrics/resource 200 OK in 2 millisecond
server.go:139] "Storing metrics"
server.go:144] "Scraping cycle complete"

# metrics-server 를 삭제했는데, k top nodes/pods 에러가 발행하지 않는다.
kubectl delete -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# top 명령을 받고 있는 별도의 pod 가 있는것으로 의심된다.
# v1beta1.metrics.k8s.io 를 사용하는 api 서비를 조회하면
kubectl get apiservices | grep -i v1beta1.metrics.k8s.io

# 다음과 같이 prometheus-adapter 서비스가 나온다.
v1beta1.metrics.k8s.io     prometheus-adapter/prometheus-adapter

# kubectl top nodes 동작하는 클러스터는 다음과 같다.
v1beta1.metrics.k8s.io     kube-system/metrics-server

# metrics-server (kind:APIService) 부분이 반영이 안되는게 문제였다.
# prometheus-adapter > v1beta1.metrics.k8s.io 를 사용하고 있고, 이를 argo-cd 에서 항상 sync 하고 있어 삭제해도 다시 생성된다.