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) 에 로그는 다음과 같다.

$ 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 에 커맨드 파라메터를 다음과 같이 추가 해주고 재시작 해줘야 한다.

--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 파일을 작성함으로서 시작된다.

$ 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 파라메터의 값과 동일해야 한다. 이제 다음과 같이 인증서를 제작한다.

$ 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 서버에 배포를 해준다.

$ 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 를 등록했기 때문에 유닛 파일을 수정해주면 된다.

$ 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

정상적으로 구동이 되었다면 이제 메트릭 서버를 재설치하면 정상적으로 작동 된다.

$ 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

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다