쿠버네티스 메트릭 서버 인증 실패

쿠버네티스 v1.11.x에서 metrics-server를 설치하였으나, 한개의 마스터 서버에서만 정상적으로 작동하는 문제가 발생하였습니다. (3개의 마스터 서버로 HA 구성 상태)

kubectl top node 명령어를 사용하면, 약 1/3 확률로 정상 응답을 하고, 나머지는 아래와 같이 권한이 없다는 메시지가 나옵니다.

F0531 10:41:33.286003 52081 helpers.go:119] error: You must be logged in to the server (Unauthorized)

그래서 kube-apiserver를 로드 밸런서 없이, 마스터 서버 아이피로 직접 연결해서 테스트해보았는데, 단 1개의 마스터 서버만 정상 응답하고, 나머지는 권한이 없다는 메시지가 나왔습니다.

metrics-server는 어그리게이션 레이어를 사용하는데, kube-apiserver와 metrics-server 간에 인증서로 상호 연동을 합니다. 문제는 해당 쿠버네티스 클러스터를 설치하는 과정에서, 이 인증서를 마스터 서버마다 따로 생성을 해버려서, 한군데만 정상적으로 작동한다는 것이였습니다. (kubeadm을 이용해서 설치하였는데, 해당 인증서를 복사해서 사용하지 않고, 서버 마다 직접 설치하여서 자동으로 생성된 경우입니다.) 그래서, 인증서를 다시 생성한 후, 각 마스터 서버에 복사하고, kube-api-server를 재시작 하였고, metrics-server를 재시작 해서 문제를 해결하였습니다.

쿠버네티스 버전이 1.11이기 때문에 kubeadm.k8s.io/v1alpha1 형식으로 파일을 만들어야 했습니다. 로드 밸런서 도메인 이름과, IP 주소, 각 마스터 서버의 IP 주소를 apiServerCertSANs 에 추가하여 kube-config.yaml 파일을 생성하였습니다

apiVersion: kubeadm.k8s.io/v1alpha1
kind: MasterConfiguration
api:
  advertiseAddress: xx.xx.xx.xx
...
apiServerCertSANs:
  - lb.xx.xx.xx
  - lb.xx.xx.xx
  - ma.xx.xx.xx
  - ma.xx.xx.xx
  - ma.xx.xx.xx

그리고 kubeadm을 실행해서 front-proxy 인증서를 생성하였습니다.

kubeadm alpha phase certs front-proxy-ca --config kube-config.yaml
kubeadm alpha phase certs front-proxy-client --config kube-config.yaml

위의 명령을 실행하면 해당 파일들이 생성됩니다.

  • front-proxy-ca.crt
  • front-proxy-ca.key
  • front-proxy-client.crt
  • front-proxy-client.key

생성한 파일들을, 나머지 마스터 서버에 복사하고, kube-api-server를 재시작합니다.

모든 마스터 서버의 작업이 끝났으면, metrics-server를 재시작합니다.

쿠버네티스 메트릭 서버(metrics-server) 설치하기

쿠버네티스 v1.11부터 heapster가 deprecated 되었습니다 (자세한 내용은 문서를 참고 바랍니다.) 그래서 HPA(horizontal pod autoscaler)나 kubectl top 명령어를 사용하라면 metrics-server를 사용해야 합니다.

Metrics Server 란?

Metrics Server는 클래스터 전체의 리소스 사용 데이터를 어그리게이션합니다. 각 노드에 설치된 kublet을 통해서 노드나 컨테인너의 CPU나 메모리 사용량 같은 메트릭을 수집합니다.

설치 방법

요구 사항

Metrics Server를 배포하려면, 쿠버네티스 클러스터에 어그리게이션 레이어가 활성화되어 있어야합니다. 대부분은 기본적으로 활성화되어 있습니다. 혹시 직접 활성화해야하는 경우라면, 아래 링크를 참조하세요. https://kubernetes.io/docs/tasks/access-kubernetes-api/configure-aggregation-layer

설치

Metrics Server git 저장소(https://github.com/kubernetes-incubator/metrics-server)를 복제(clone)하고, 다음과 같이 설치하세요.

git clone https://github.com/kubernetes-incubator/metrics-server.git
cd metrics-server
kubectl apply -f deploy/1.8+/

kubectl을 이용해서 적용하면, v1beta1.metrics.k8s.io 라는 apiservce가 생성되고, metrics-server 라는 디플로이먼트와 서비스가 생성됩니다.

설치가 잘 진행되었다면, 다음과 같이 apiservice를 확인할 수 있습니다.

kubectl get apiservices | grep metrics

v1beta1.metrics.k8s.io                 2019-05-31T06:24:16Z

그리고 디플로이먼트와 서비스도 확인할 수 있습니다

kubectl -n kube-system get deploy,svc | grep metrics-server

deployment.extensions/metrics-server               1         1         1            1           1h
service/metrics-server               ClusterIP   10.96.106.172   <none>        443/TCP         1h

kubectl top node 명령어를 사용하면, 노드의 사용현황을 볼 수 있습니다.

$ kubectl top node
NAME                           CPU(cores)   CPU%      MEMORY(bytes)   MEMORY%
kube-node-001                  9736m        24%       99265Mi         38%
kube-node-002                  12060m       30%       115793Mi        44%
kube-node-003                  12349m       30%       117894Mi        45%
kube-master-001                248m         0%        20110Mi         7%
kube-master-002                289m         0%        7035Mi          2%
kube-master-003                268m         0%        7087Mi          2%

Troubleshooting

metrics-server 의 포드에 다음과 같은 에러 로그가 있을 경우, 파라메터를 추가해야합니다.

E0531 08:27:57.249840       1 manager.go:111] unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:kube-xxxx: unable to fetch metrics from Kubelet kube-xxx (kube-xxx): Get https://kube-xxx:10250/stats/summary/: dial tcp: lookup kube-xxx on xx.xx.xx.xx:x: no such host]

E0531 08:34:42.750007       1 manager.go:111] unable to fully collect metrics: [unable to fully scrape metrics from source kubelet_summary:kube-xxxx: unable to fetch metrics from Kubelet kube-xxx (xx.xx.xx.xx): Get https://xx.xx.xx.xx:10250/stats/summary/: x509: cannot validate certificate for xx.xx.xx.xx because it doesn't contain any IP SANs]

dial tcp: lookup kube-xxx on xx.xx.xx.xx:x: no such host 에러인 경우에는 kubelet-preferred-address-types 파라메터를, x509: cannot validate certificate for xx.xx.xx.xx because it doesn't contain any IP SANs인 경우에는 kubelet-insecure-tls 파라메터를 사용하면 된다.

metrics-server-deployment.yaml 파일을 편집해서, image: k8s.gcr.io/metrics-server-amd64:v0.3.3 밑에다 아래 파라메터를 추가하면 됩니다.

        command:
          - /metrics-server
          - --kubelet-preferred-address-types=InternalIP
          - --kubelet-insecure-tls

Unable to get metrics for resource cpu

상황

쿠버네티스 v1.11.x에서 HPA를 사용하려고 했으나, 에러가 발생하였습니다.

에러 메시지

Warning  FailedGetResourceMetric       3m (x21 over 13m)  horizontal-pod-autoscaler  unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io)

해결 방법

위의 에러 메시지는는 metrics-server가 설치되어 있지 않아서 생기는 것입니다. metrics-server 설치 문서를 참고해서 설치 하시기 바랍니다.