extension-apiserver 란?
쿠버네티스(Kubernetes)가 발전에 따라서 많은 변화를 겪었다. 최신의 버전에서 extension apiserver 라는 것을 필요로하는 경우가 많다. 이것은 쿠버네티스 문서에서는 aggregation layer 라고 설명하고 있다.
Configuring the aggregation layer allows the Kubernetes apiserver to be extended with additional APIs, which are not part of the core Kubernetes APIs
애그리게이션 레이어 설정은 쿠버네티스 API 코어의 일부가 아닌 추가적인 API를 가지고 확장될 수 있는 쿠버네티스 apiserver 를 가능하게 한다.
Configure the Aggregarion Layer
최근에 구축한 쿠버네티스 서버에 메트릭 서버(Metric Server) 를 설치했는데 제대로 작동되지 않아 왜 그런가 봤더니 바로 이 문제였다. 메트릭 서버 파드(Pod) 에 로그는 다음과 같다.
1 2 3 4 |
$ kubectl logs metrics-server-57b8795b4c-hgnlt -n kube-system E0423 10:51:25.342066 1 configmap_cafile_content.go:243] kube-system/extension-apiserver-authentication failed with : missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file" E0423 10:51:25.342153 1 configmap_cafile_content.go:243] key failed with : missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file" E0423 10:51:25.347263 1 configmap_cafile_content.go:243] kube-system/extension-apiserver-authentication failed with : missing content for CA bundle "client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file" |
메시지를 보면 extension-apiserver-authentication 등의 메시지를 볼 수 있다. 문제는 이런 로그가 남는다고 해서 메트릭 서버 파드의 상태가 Running 으로 된다는 것이다. 파트 상태가 Running 이라고 해서 메트릭 서버가 정상으로 작동되는 것은 아닌게 문제의 핵심이다.
이 문제를 해결하기 위해서는 extension-apiserver 기능을 apiserver 가 가지도록 해야 한다. 이것은 kube-apiserver 에 커맨드 파라메터를 다음과 같이 추가 해주고 재시작 해줘야 한다.
1 2 3 4 5 6 7 |
--requestheader-client-ca-file=<path to="" aggregator="" ca="" cert=""> --requestheader-allowed-names=front-proxy-client --requestheader-extra-headers-prefix=X-Remote-Extra- --requestheader-group-headers=X-Remote-Group --requestheader-username-headers=X-Remote-User --proxy-client-cert-file=<path to="" aggregator="" proxy="" cert=""> --proxy-client-key-file=<path to="" aggregator="" proxy="" key=""> |
요구사항을 보면 인증서가 필요하다는 것을 알게 된다. 인증서 제작은 Kubernetes Hard Way 문서에 잘 정리되어 있다. 필자는 쿠버네티스 하드 웨이 방법을 구축한 서버이기에 이 과정을 진행해 볼 수 있었다.
extension apiserver 를 위한 인증서 작성
인증서 작성은 다음과같이 CSR 파일을 작성함으로서 시작된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ cat > proxy-client-csr.json <<EOF { "CN": "front-proxy-client", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "US", "L": "Portland", "O": "system:masters", "OU": "Kubernetes The Hard Way", "ST": "Oregon" } ] } EOF |
여기서 주의해야 할 것이 조직(O) 를 system:masters 로 해야 하며, CN 은 –requestheader-allowed-names 파라메터의 값과 동일해야 한다. 이제 다음과 같이 인증서를 제작한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=kubernetes \ proxy-client-csr.json | cfssljson -bare proxy-client 2021/04/23 14:54:09 [INFO] generate received request 2021/04/23 14:54:09 [INFO] received CSR 2021/04/23 14:54:09 [INFO] generating key: rsa-2048 2021/04/23 14:54:09 [INFO] encoded CSR 2021/04/23 14:54:09 [INFO] signed certificate with serial number 534282701421151901323513822674041149219991213452 2021/04/23 14:54:09 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org); specifically, section 10.2.3 ("Information Requirements"). $ ls proxy-client* proxy-client.csr proxy-client-csr.json proxy-client-key.pem proxy-client.pem |
이제 이것을 각 master 서버에 배포를 해준다.
1 2 3 |
$ sudo cp proxy-client*.pem /var/lib/kubernetes/ $ scp proxy-client*.pem systemv@kmaster2.systemv.local:./ $ scp proxy-client*.pem systemv@kmaster3.systemv.local:./ |
kube-apiserver 커맨드 파라메터 수정
배포를 모두 했다면, 이제 kube-apiserver 에 커맨드 파라메터를 수정해 줘야 한다. systemd 에 kube-apiservere 를 등록했기 때문에 유닛 파일을 수정해주면 된다.
1 2 3 4 5 6 7 8 9 10 11 |
$ sudo vim /etc/systemd/system/kube-apiserver.service --requestheader-client-ca-file=/var/lib/kubernetes/ca.pem \ --requestheader-allowed-names=front-proxy-client \ --requestheader-extra-headers-prefix=X-Remote-Extra- \ --requestheader-group-headers=X-Remote-Group \ --requestheader-username-headers=X-Remote-User \ --proxy-client-cert-file=/var/lib/kubernetes/proxy-client.pem \ --proxy-client-key-file=/var/lib/kubernetes/proxy-client-key.pem \ --enable-aggregator-routing=true \ $ sudo systemctl daemon-reload $ sudo systemctl restart kube-apiserver |
정상적으로 구동이 되었다면 이제 메트릭 서버를 재설치하면 정상적으로 작동 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ kubectl logs metrics-server-57b8795b4c-cn8x5 -n kube-system I0423 15:24:40.014008 1 serving.go:325] Generated self-signed cert (/tmp/apiserver.crt, /tmp/apiserver.key) I0423 15:24:40.367149 1 requestheader_controller.go:169] Starting RequestHeaderAuthRequestController I0423 15:24:40.367169 1 shared_informer.go:240] Waiting for caches to sync for RequestHeaderAuthRequestController I0423 15:24:40.367192 1 configmap_cafile_content.go:202] Starting client-ca::kube-system::extension-apiserver-authentication::client-ca-file I0423 15:24:40.367196 1 shared_informer.go:240] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::client-ca-file I0423 15:24:40.367205 1 configmap_cafile_content.go:202] Starting client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file I0423 15:24:40.367208 1 shared_informer.go:240] Waiting for caches to sync for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file I0423 15:24:40.367785 1 secure_serving.go:197] Serving securely on [::]:4443 I0423 15:24:40.368038 1 dynamic_serving_content.go:130] Starting serving-cert::/tmp/apiserver.crt::/tmp/apiserver.key I0423 15:24:40.368072 1 tlsconfig.go:240] Starting DynamicServingCertificateController I0423 15:24:40.467350 1 shared_informer.go:247] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::requestheader-client-ca-file I0423 15:24:40.467480 1 shared_informer.go:247] Caches are synced for client-ca::kube-system::extension-apiserver-authentication::client-ca-file I0423 15:24:40.467636 1 shared_informer.go:247] Caches are synced for RequestHeaderAuthRequestController |