Skip to Content
Infra & DevOpsK8s 1.15->1.16 메이저 업그레이드 대응
☁️ Infra & DevOps2019년 10월 1일

K8s 1.15->1.16 메이저 업그레이드 대응

#kubernetes#infra-devops#kubeadm#prometheus#troubleshooting

1. 1.16 메이저 업데이트와 API 폐쇄 징후

쿠버네티스 역사상 1.16 버전은 DevOps 및 인프라 엔지니어들에게 악명 높은 ‘대격변’의 릴리즈로 기억됩니다. 오랫동안 암묵적으로 허용되어 온 구형 API(v1beta1, v1beta2 등)가 대거 삭제되고, 파드 메트릭 라벨 네이밍이 싹 바뀌었으며, CoreDNS 플러그인 생태계에도 큰 변경이 있었기 때문입니다. 클러스터 환경에서도 기존 1.15.x 절차대로 단순 패키지 업그레이드만 돌렸다가, 수많은 모니터링 파드가 수집을 멈추고 API 호출이 실패하는 쓴맛을 보았습니다. 이때 겪었던 정규 업그레이드 절차와 후속 장애 조치(Troubleshooting) 내역을 병합해 정리합니다.

2. Deprecated API의 이해

업그레이드 명령어 자체는 이전 버전(1.14->1.15)과 크게 다르지 않은 kubeadm upgrade 기반입니다. 하지만 진짜 중요한 것은 1.16으로 올라가는 클러스터 내부 워크로드의 스펙(API, 라벨, DNS) 변화 대응입니다.


1부. 기본 업그레이드 절차 (1.15 -> 1.16.0)

마스터 노드 (Control Plane)

bash
# Kubeadm 업그레이드 $ sudo apt-cache policy kubeadm $ sudo apt-mark unhold kubeadm $ sudo apt-get update $ sudo apt-get install -y kubeadm=1.16.0-00 $ sudo apt-mark hold kubeadm # 플랜 검증 및 컨트롤 플레인 적용 $ sudo kubeadm upgrade plan $ sudo kubeadm upgrade apply v1.16.0 # Kubelet / Kubectl 데몬 재시작 $ sudo apt-mark unhold kubelet kubectl $ sudo apt-get update $ sudo apt-get install -y kubelet=1.16.0-00 kubectl=1.16.0-00 $ sudo apt-mark hold kubelet kubectl $ sudo systemctl restart kubelet

워커 노드 (Worker Node)

bash
$ sudo apt-mark unhold kubeadm $ sudo apt-get update $ sudo apt-get install -y kubeadm=1.16.0-00 $ sudo apt-mark hold kubeadm $ sudo kubeadm upgrade node $ sudo apt-mark unhold kubelet kubectl $ sudo apt-get update $ sudo apt-get install -y kubelet=1.16.0-00 kubectl=1.16.0-00 $ sudo apt-mark hold kubelet kubectl $ sudo systemctl restart kubelet

2부. 주요 장애 및 트러블슈팅 (Troubleshooting)

이 1.16 업그레이드 직후에는 시스템이 정상인 것처럼 보여도 속으로는 곪아 터지는 세 가지 심각한 이슈가 발생했습니다.

이슈 1. CoreDNS Plugin Deprecated 에러

kubeadm upgrade plan 또는 apply 시 다음과 같은 Fatal 수준의 프리플라이트(Preflight) 에러가 발생하며 업그레이드가 거부될 수 있습니다.

[ERROR CoreDNSUnsupportedPlugins]: there are unsupported plugins in the CoreDNS Corefile

  • 원인: 기존 CoreDNS의 proxy 플러그인이 1.16 지원 DNS 규격에서 완전히 폐기(deprecated)되었고 forward 플러그인으로 대체되어야 하기 때문입니다.
  • 해결: 에러 메시지를 무시하고 강제로 진행하는 플래그를 넘겨주면, kubeadm이 똑똑하게 구형 proxy 코어파일 지시자를 forward로 자동 치환해줍니다.
    bash
    $ sudo kubeadm upgrade apply v1.16.0 --ignore-preflight-errors=CoreDNSUnsupportedPlugins

이슈 2. Prometheus 모니터링 메트릭(Metric) 무수집 장애

업그레이드 직후, 그라파나(Grafana) 대시보드에 파드 메트릭 지표가 빈 깡통으로 렌더링되었습니다.

  • 원인: K8s 1.16부터 핵심 컨테이너 메트릭 지표(cadvisor)의 라벨 명칭이 짧게 변경되었습니다. (1.16 릴리즈 노트 참고 )
    • container_name -> container
    • pod_name -> pod
  • 해결: 프로메테우스의 스크랩핑 타겟 설정 파일(prometheus.yaml)에서 리라벨(relabel) 설정의 source_labels 매핑을 변경해줘야 합니다.

[AS-IS] 기존 1.15용 Prometheus Config

yaml
metric_relabel_configs: - source_labels: [namespace] target_label: xm_namespace - source_labels: [pod_name] # <--- 변경 대상 target_label: xm_pod_id - source_labels: [container_name] # <--- 변경 대상 target_label: xm_cont_name

[TO-BE] 수정된 1.16용 Prometheus Config

yaml
metric_relabel_configs: - source_labels: [namespace] target_label: xm_namespace - source_labels: [pod] # <--- 변경 완료 target_label: xm_pod_id - source_labels: [container] # <--- 변경 완료 target_label: xm_cont_name

이슈 3. API Version (v1beta1) 일괄 삭제에 따른 배포 파이프라인 중단

K8s 1.16에서는 레거시 환경에서 널리 쓰이던 apps/v1beta1, apps/v1beta2, extensions/v1beta1 스펙의 Deployment, DaemonSet, StatefulSet, ReplicaSet API가 깡그리 삭제되었습니다.

  • 원인 & 파급: 개발팀이 CD 도구에 심어놓은 기존 수백 개의 YAML 배포 매니페스트들이 API 버전을 인식하지 못해 배포 실패 error: unable to recognize "deployment.yaml" 를 뿜어냅니다.
  • 해결: 모든 YAML 파일의 상단 API 선언부를 다음과 같이 수정해야 합니다.
    yaml
    # 기존 apiVersion: extensions/v1beta1 kind: Deployment # 1.16 이후 변경 apiVersion: apps/v1 kind: Deployment

4. 메이저 업그레이드 무사 완료 회고

1.16 업데이트 사태는 기술 부서에 거대한 충격을 안겼습니다. “운영되는 인프라 버전을 무작정 최신으로 올려서는 절대 안 된다”, “미디엄이나 마이너 버전이라도 주요 Deprecation 공지(Release Notes)를 팀 단위로 철저히 분석 후 스크립트를 마이그레이션해야 한다”는 강렬한 교훈을 얻은 프로젝트였습니다. 이 경험 덕분에 추후 플랫폼 스택 전체의 하위 호환성을 검증하는 별도의 스테이징 리뷰 파이프라인이 정립되었습니다.

Last updated on