기술 이모저모/[K8s] Kubernetes

[k8s] helm upgrade fail, remove api 조치 방안

Kobby 2023. 2. 5. 15:43

개인적으로 차근차근 공부하는 목적으로 작성한 글입니다.

일부 잘못된 내용이 있을 수도 있습니다. 잘못된 내용은 피드백 해주시면 적극 반영하도록 하겠습니다.

감사합니다 :)


최근 쓰니가 재직중인 회사에서 Cluster Upgrade가 있었다. 근데 Upgrade 이후, 특정 Github 레포의 helm upgrade가 되지 않는 이슈가 있었고 이를 통해 새롭게 알게 된 내용을 정리하고자 한다.

 

Github Action Helm upgrade Fail

Error: UPGRADE FAILED: current release manifest contains removed kubernetes api(s) for this kubernetes version and it is therefore unable to build the kubernetes objects for performing the diff. error from kubernetes: unable to recognize "": no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"

Fail 로그

위 말 그대로 해석해보면 현재 배포된 manifest에 현재 버전에서 사라진 k8s api가 존재하기 때문에 Fail이 발생하였다.

맞다! 기존 k8s 버전에서는 Ingress.v1beta1을 사용하고 있었다. 하지만 Upgrade 되 k8s에서는 ingress.v1을 사용해야 한다.

 

그래서 배포되는 Helm Chart를 모두 ingress.v1으로 수정해서 배포했는데도 위와 같은 오류가 계속 발생해서 당황하였다.


Helm upgrade fail 원인

Helm을 조금 더 찾아보니, 그 원인은 helm upgrade 시에는 기존 배포 된 manifest와 신규 배포될 manifest를 비교하여 신규 배포되는 helm에 대한 변경사항을 알아보는 과정이 있다. 이때 upgrade 이후 cluster에서는 기존 배포 된 manifest의 ingress.v1beta1을 지원하지 않기 때문에 변경사항을 알 수 없고 그래서 upgrade에 실패를 하게 된것이다.

 

그렇다면 이슈 해결은 어떻게 할 수 있을까? 조치 방법은 크게 아래와 같이 2가지가 있다.


Helm upgrade 조치 방법

조치 방법 : helm rollback

Helm upgrade Fail에 대한 가장 쉬운 조치 방법은 rollback하는 방법이다. 하지만 쓰니의 상황에서는 이 방법이 적용되지 않았다.

왜냐하면 이전 helm 배포는 모두 ingress.v1beta1을 사용하였고 clouster upgrade를 했기 때문에 rollback을 할 수 없었다.

마지막 방법은 기존 배포 된 Helm manifest 정보를 변경하는 것이다.

 

조치 방법 : helm uninstall

쓰니의 경우 회사의 배포 버전이기 때문에 helm uninstall release --keep-history로 삭제하였다.

그렇기 떄문에 온전히 삭제됬다고 보기는 어렵고, 이 상태에서 helm upgrade를 하면 에러가 났었다. 근데 즉시 조치가 필요하거나 helm history가 굳이 필요하지 않다면 helm 정보 전체를 삭제한 다음에 다시 배포하는것이 가장 빠른 조치 방법이다.

 

조치 방법 : helm manifest 파일 변경

우선 helm chart로 배포된 정보는 아래와 같이 kubectl secret으로 관리된다. (이걸 알아내기까지 많은 시간이 걸렸다..)

secret으로 관리되는 helm deploy 정보

그래서 현재 helm ls로 배포되는 revision.79의 status values와 secrete의 .79 정보가 동일함을 알 수 있다.

helm ls 정보
helm manifest 정보의 secret

helm upgrade를 할 경우 배포되는 release의 status=deployed의 secret을 찾아서 배포 할 helm chart와 비교하는 것이다.

문제는 secret 정보가 평문으로 저장되어 있다면, 수정하기가 수월했겠지만 secret 정보이기 때문에 인코딩되어 정보를 저장한다.

 

여기서부터는 helm docs의 아래 정보를 참고하였다.

 

Deprecated Kubernetes APIs

Explains deprecated Kubernetes APIs in Helm

helm.sh

helm secret

helm chart info secret을 변경하는 방법은 아래와 같고, 최종적으로 수정 된 manifest secret 정보를 반영 한 다음에 helm upgrade를 하면 문제가 해결된다!!!

1. 현재 secret 정보를 백업한다.

2. 현재 secret 정보의 manifest를 담고 있는 data.release를 디코딩한다.
 - |base64 -d |base64 -d |gzip -d 로 3번의 디코딩 과정을 거쳐야 한다.

3. 디코딩하여 평문으로 변환 된 manifest 정보 중에서 내가 수정하고자 하는 정보를 수정한다.

 - secret 정보에 다시 넣기 위해서 인코딩 한다.

4. 디코딩의 역순으로 gzip부터 총 3번의 인코딩을 해야 한다. |gzip |base64 |base64


5. 인코딩 된 정보를 본래의 secret.data.release에 업데이트한 다음에 다시 helm upgrade를 한다.

 

secret 디코딩으로 확인할 수 있는 정보

위에서 말했듯이 helm chart 배포 정보를 secret으로 저장하고 있으며, template/manifest 정보를 알 수 있다.

하지만 template은 base64으로 한번 더 인코딩되어 있기 떄문에 실제 평문 정보를 얻기 위해서는 다시 한번 디코딩해야 한다.

template info

secret의 디코딩 된 정보에서 하단으로 내리면 manifest info를 알 수 있고, 결과적으로는 아래와 같이 apiVersion 그리고 이에 따라 변경되는 values 값을 수정하고 인코딩 한 다음에 해당 정보를 다시 secret에 반영하며 된다.

디코딩 된 manifest 정보

 

Helm docs의 권장사항을 보면 아래와 같이 Cluster upgrade 이전에 API 버전을 upgrade 하는것을 권고하고 있다.

Cluster upgrade 이전에 살펴보긴 했는데, 모든 레포의 heml api를 살펴보지 않아서 이런 문제가 발생한것 간다.

 

권장 사항: 가장 좋은 방법은 더 이상 사용되지 않는 API를 사용하여 릴리스를 업그레이드하는 것입니다. kubernetes 클러스터로 업그레이드하기 전에 버전을 지원되는 API 버전으로 해당 API 버전을 제거합니다.

 

왜 helm upgrade가 안되는지 한참 찾아보고, 고민했었는데 다음번 Cluster upgrade 할 때는 미리 api 버전까지 모두 다 확인해야 될것 같다.

 

아직 배울게 많다!!