ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 쿠버네티스 모범 사례) Ch.1 - Ch.4 정리
    네트워크 & 인프라 2024. 3. 31. 13:57

     

     

     

     

     

     

    최근 쿠버네티스 모범 사례 스터디를 시작했는데, 책을 보면서 정리한 내용을 정리했다.

    책은 쿠버네티스 창시자가 작성했다고 한다!

    https://www.yes24.com/Product/Goods/95560470?pid=123487&cosemkid=go16063008668169695&gad_source=1&gclid=Cj0KCQjw8J6wBhDXARIsAPo7QA-xAfzqEuCjQvl9VCNjItXivOvmv99vFsQ-JSS8N0tv6_d-028SVBwaAqqEEALw_wcB

     

    쿠버네티스 모범 사례 - 예스24

    이 책은 쿠버네티스 창시자인 브렌던 번스와 분산 시스템, 기업용 애플리케이션 개발, 오픈 소스에 조예가 깊은 세 명의 쿠버네티스 전문가가 함께 썼다. 현업에서 쌓은 경험을 바탕으로 쿠버네

    www.yes24.com

     

     

     

     

     

     

    Ch1. 기본 서비스 설치

     

    1.2 설정 파일 관리

    • 쿠버네티스에서는 모든 것을 선언적으로 표현
    • 쿠버네티스는 YAML과 JSON을 지원
      • YAML에서 들여쓰기를 주의

    1.3.1 이미지 관리 모범 사례

    • 컨테이너 이미지를 구축하는 과정은 ‘공급망 공격’(supply chain attack)에 취약
      • 공급망 공격 : 신뢰할 수 있는 소스의 의존 이미지에 악의적인 사용자가 코드나 바이너리를 삽입하여 독자의 어플리케이션에 내장
      • 해결방법
        • 믿을 수 있는 이미지 공급자를 통해서 이미지 구축
        • 밑바닥부터 이미지를 구축 (이때, 정적 바이너리를 구축할 수 있는 언어를 사용하는 것이 수월)
    • 네이밍 모범 사례
      • 버전태그를 변경하지 않기 위해서 의미론적 버전과 이미지가 빌드된 커밋의 sha 해시와 결합해 네이밍
        • ex) v1.0.1-bfeda01f
      • 버전태그를 명시하지 않으면 latest가 기본 설정
        • 운영에서는 이미지 구축마다 이미지 자체가 변경되어 좋지 않음

    1.3.2 어플리케이션 레플리카 생성

    • 프론트엔드 앱은 stateless
      • 예상치 못한 장애에 대응하거나 롤아웃을 위해 재시작 다운타임을 방지하기 위해 최소 두개의 레플리카를 실행하는 것이 좋음
    • 쿠버네티스에서는 replicaSet보다 deployment 리소스를 사용하여 레플리카를 관리하는 것을 권장
    • 컨테이너의 리소스 요청과 제한
      • 요청 : 앱을 실행하는 호스트 장비가 보장해주는 리소스 크기
      • 제한 : 컨테이너가 사용할 수 있는 최대 리소스 크기
      • 동일한 값으로 설정이 리소스 이용률을 높일 수는 없지만, 앱이 에상대로 동작하므로 안정성을 얻을 수 있음
    • 소스관리와 운영을 일치시키기 위해 gitOps로 CI와 CD를 자동화 하여 특정 브랜치에만 배포

    1.4 HTTP 트래픽을 처리하는 외부 ingress 설정

    • 클러스터 리소스는 기본적으로 오직 클러스터 내에서만 접근 가능
      • 외부 노출을 위해서 외부 IP 주소를 할당해주는 서비스와 로드밸런서를 생성하고 컨테이너로 트래픽을 보내야함
        • TCP 또는 UDP 트래픽을 로드밸런싱 하는 서비스 + Ingress 리소스
          • Ingress 리소스 : HTTP 경로와 호스트 기반의 요청을 지능적으로 라우팅할 수 있는 HTTP(S) 로드 밸런싱 지원
      • 단순한 앱 조차도 두개의 다른 서비스의 HTTP 요청을 처리 → Ingress 선택 이유
      • 클러스터에서 인그레스 동작을 위해서 서비스리소스와 달리 인그레스 컨트롤러 컨테이너가 필요
        • Ingress 공급자 : nginx, haproxy 등

    1.5 ConfigMap으로 애플리케이션 설정

    • 애플리케이션과 설정을 분리하는 것이 필요
      • 바이너리 환경에 따라 달라지는 설정을 적용
      • 새로운 기능 코드로 활성화한다면 매번 빌드해서 바이너리 배포해야함
    • ConfigMap : 설정 정보나 파일을 나타내를 다중 키/값 쌍
      • 변경된 설정을 정기적으로 Deployment에 적용해 롤아웃 → configmap의 이름에 버전 숫자를 넣어 deployment가 적절한 health check를 통해서 자동으로 멈췄다가 재시작
        • 단순 configmap 자체를 변경하면 이미 존재하는 파드가 실제로 갱신되지 않고 파드를 재시작 해야 설정이 반영 → health check를 통해서가 아닌 불시에 또는 무작위로 롤아웃 될 수 있음

    1.6 시크릿 인증 관리

    • Secret : 설정과는 다른 방식으로 접근 제어, 처리, 갱신
      • 쿠버네티스는 시크릿 데이터를 다룰 수 있는 시크릿 리소스를 제공
        • Microsoft Azure key vault나 해시코프 볼트와 같은 오픈 소스 프로젝트를 활용한 시크릿/키관리 서비스를 사용하는 것이 좋다
        • 기본적으로 시크릿은 암호화 되지 않은 상태로 쿠버네티스에 저장됨
      • 볼륨을 사용하여 배포 시점에 실행중이 애플리케이션과 시크릿을 결합해야 함
        • 시크릿은 tmpfs 램 기반의 파일시스템으로 볼륨을 생성해 컨테이너에 마운트하여 장비가 물리적인 피해를 입더라도 공격자가 시크릿을 취득하기 어려움

    1.7 간단한 스테이트풀 데이터베이스 배포

    • 쿠버네티스에서는 노드 상태, 업그레이드, 리밸런싱 등 여러 이유로 파드가 다시 스케줄링됨
      • 데이터가 특정 장비나 컨테이너 자체에 존재하는 경우 컨테이너가 이관되거나 재시작될 때 데이터 손실발생
      • ⇒ PersistentVolume을 사용해서 방지 가능
        • 원격 스토리지에 존재
        • 파일 기반의 네트워크 파일 시스템 (NFS), 서버 메세지 블록(SMB) 등 다양한 네트워크 프로토콜을 통해 마운트
        • StatefulSet 리소스를 사용해 배포해 강한 일관성을 보장
        • 싱글턴 패턴으로 배포할 때는 상대적으로 덜 중요하지만 상태 복제를 배포할 때는 유용
        • 레디스는 PersistentVolumeClaim을 사용해서 PersistentVolume을 얻음
          • 볼륨클레임을 사용해 작성한 템플릿은 복제가 가능하고 각 파드는 자신만의 persistentVolume을 할당 받을 수 있음

    1.8 서비스를 이용한 TCP 로드 밸런서 생성

    • 읽기 : statefulSet의 레플리카에 모두 데이터가 복제되어 있어 어디서 요청을 처리하든 상관 없음
    • 쓰기 : 레디스 마스터에서 직접 처리, 클러스터 IP주소를 가지지 않는 헤드리스 서비스를 이용
      • 대신, statefulSet안의 모든 파드에 대한 DNS를 설정
      • 트랜잭션 읽기 / 쓰기를 위해 레디스에 연결하는 경우, 별도의 클라이언트를 구축하여 쓰기 서버에 연결

    1.9 인그레스에 이용해 트래픽을 정적 파일 서버로 전달

    • nginx 컨테이너 기반으로 정적 이미지를 구축해 각 레플리카에 배포

    1.10 헬름을 이용한 애플리케이션 파라미터화

    • 모든 파일을 서로 동기화 된 상태로 유지해야하기 때문에 쉽게 개발하기 위해서 브랜치와 버전관리를 사용
      • 템플릿 시스템 : 애플리케이션 설정의 뼈대인 템플릿과 특정 환경 설정으로 템플릿을 특수하게 만들어주는 파라미터를 결합
        • ex) helm (chart)

    1.11 서비스 배포 모범 사례

    • 대부분의 서비스는 Deployment 리소스로 배포되어야 함
    • Deployment는 로드 밸런서인 서비스를 통해 노출 , HTTP 애플리케이션을 노출하려면 인그레스 컨트롤러를 사용할 수 있으며 요청 라우팅과 SSL도 추가할 수 있음
    • 애플리케이션의 설정을 다양한 환경에서 재사용하려면 애플리케이션을 파라미터화 해야함

     

     

     

     

     

     

     

     

    Ch2. 개발자 워크플로

     

    2.2 개발 클러스터 구축

    • 대규모 단일 개발 클러스터는 개발자별 클러스터에 비해 효율적임
      • 개발자 사이의 충돌은 충분히 관리가 가능

    2.3 다중 개발자를 위한 공용 클러스터 구축

    • 쿠버네티스의 네임 스페이스 이용
      • 서비스 배포 범위를 제한하여 특정 사용자의 프론트엔드 서비스가 다른 사용자의 프론트엔드 서비스에 피해를 주지 않도록

    2.3.1 사용자 온보딩

    • 쿠버네티스 클러스터 접근 방법
      1. 증명 기반 인증
        1. 새로운 증명을 생성하여 로그인에 사용할 수 있는 kubeconfig파일 전달
      2. 외부 신원 시스템 ⇒ 신원 데이터를 한곳에서 관리할 수 있어 모범 사례
        1. aws Identity and Access Managament(IAM)을 이용해 클러스터 접근 설정

    2.3.2 네임스페이스 생성과 보안

    • 일반적으로 annotation 형태
      • 환경 안의 사용자에게 RoleBinding
      • 클러스터의 시크릿 리소스에 접근할 수 있기 때문에 읽기 권한을 부여할 때에는 주의해야 함
    • 틀정 네임스페이스의 리소스 사용량을 제한하고 싶다면 리소스 쿼터(ResourceQuota)를 사용

    2.3.3 네임스페이스 관리

    • 네임스페이스 할당 방법
      1. 개발자에게 네임스페이스 부여 → 가비지 컬렉션 어려움
      2. TTL (time to live)로 네임 스페이스를 임시로 생성하여 할당 → 네임스페이스 삭제 자동화 구축 가능
        1. 네임스페이스를 조사하여 TTL이 만료된 것들을 삭제하는 스크립드를 생성
    • 쿠버네티스와 통합한다면 kubectl 도구를 이용하여 네임스페이스를 생성하고 할당할 수 있는 사용자 리소스 정의 (CRD) 구현 가능
      • RBAC : 선언적으로 네임스페이스를 관리

    2.3.4 클러스터 단위의 서비스

    • 클러스터 단위의 서비스 : IAAS(Infrastructure As A Service)
      • kubectl logs를 이용하여 로그에 접근이 가능하지만, 길이 제한이 있으며 검색이 불가

    2.6 반복적 개발

    • 컨테이너 이미지를 빌드하고 푸시한 후에는 이를 클러스터에서 실행
      • 가용성이 중요하지 않기 때문에 새로운 코드를 배포하는 가장 쉬운 방법은 기존 Deployment를 삭제하고 새로운 이미지를 가르키는 Deployment를 생성하는 것 → 모범 사례
        • 기존 Deployment를 직접 수정하면 디플로이먼트 리소스 롤아웃 로직이 동작하여 위험

    2.8 개발 환경 설정 모범 사례

    • 개발자 경험을 온보딩, 개발, 테스팅 세단계로 나누어 생각
    • 대규모 단일 클러스터가 더 나은 방법
    • 클러스터 사용자 추가시 사용자 신원을 추가하고 자신의 네임스페이스에만 접근 허용, 사용할 수 있는 리소스 크기는 제한
    • 스크립트를 이용해 네임스페이스 정리 자동화
    • 로그와 모니터링 같은 클러스터 수준의 서비스를 고민

     

     

     

     

     

     

    Ch3. 모니터링과 로깅

     

    3.1 메트릭 vs 로그

    • 메트릭 : 특정 기간에 측정한 일련의 숫자
    • 로그 : 시스템을 탐색적으로 분석하기 위해 사용

    3.2 모니터링 기술

    • 블랙박스 모니터링 : 애플리케이션 외부에 초점
      • 인프라 수준의 모니터링에 유용
      • 애플리케이션 동작을 파악하는데는 어려움
    • 화이트박스 모니터링 : 애플리케이션 상태에 초점

    3.3 모니터링 패턴

    • 쿠버네티스에서는 파드가 매우 동적이며 라이프 사이클이 짧으므로 쿠버네티스만의 특성을 고려하여 모니터링을 진행해야 함
    • 분산시스템 모니러팅 패턴 (USE와 RED는 서로 상호 보완적)
      • USE : 인프라 컴포넌트에 초점
        • Utilization : 사용률
        • Saturation : 포화도
        • Error : 오류율
      • RED : 사용자의 서비스 사용 경험에 더욱 초점 (최종 UX 모니터링에 초점)
        • Request : 요청
        • Error : 오류율
        • Duration : 소요 시간

    3.4 쿠버네티스 메트릭 개요

    • 쿠버네티스 컴포넌트
      • 컨트롤 플레인 컴포넌트
        • API 서버, etcd, 스케줄러, 컨트롤러 관리자
      • 워커 노드
        • kubelet, 컨테이너 런타임, kube-proxy, kube-dns 파드

    3.4.1 cAdvisor

    • 실행중인 컨테이너의 리소스와 메트릭 수집

    3.4.2 메트릭 서버

    • 쿠버네티스 메트릭 서버와 API
      • 리소스 메트릭 API의 표준 구현체가 메트릭 서버
        • CPU와 메모리 같은 리소스 메트릭 수집
        • HPA(horizontal pod autoscaler), VPA(vertical pod autoscaler)에서 사용됨
      • 사용자 정의 메트릭 API를 이용해 모니터링 시스템에서 임의의 메트릭 수집 가능

    3.4.3 kube-state-metrics

    • 쿠버네티스에 저장된 오브젝트를 모니터링 할 수 있는 쿠버네티스 추가 기능

    3.6 모니터링 도구

    • 프로메테우스
      • 시스템 모니터링과 알림, 툴킷 오픈 소스
    • InfluxDB
      • 높은 쓰기와 질의 부하를 처리하도록 설계된 시계열 데이터베이스
    • 데이터 독
      • 클라우드 규모의 애플리케이션을 위한 모니터링 시스셈 (SaaS 기반 데이터 분석 플랫폼을 통해 서버 모니터링 가능)
    • 시스딕
      • 컨테이너 네이티브 앱을 위한 도커와 쿠버네티스 모니터링 제공 상용 도구
    • 클라우드 공급자 도구
      • GCP 스택 드라이버
        • 구글 쿠버네티스 엔진 클러스터를 모니터링하도록 설계
      • 컨테이너를 위한 마이크로소프트 애저 모니터
        • 컨테이너 워크로드의 성능을 모니터링
      • AWS 컨테이너 인사이트
        • 아마존 클라우드 워치 컨테이너 인사이트
    • ⇒ 시계열 데이터 베이스는 키/값 쌍으로 저장하기 때문에 높은 수준의 메트릭 속성을 보여줄 수 있음

    3.7 프로메테우스 모니터링

    • 메트릭 수집을 위해 풀 모델 사용
      • 쿠버네티스는 프로메테우스 포맷으로 메트릭을 보내어 간단하게 메트릭 수집 가능
      • 클러스터와 별도의 유틸리티 클러스터에서 모니터링 하는 것이 모범 사례
    • 프로메테우스 서버
      • 시스템으로부터 수집된 메트릭을 가져와 저장
    • 프로메테우스 오퍼레이터
      • 프로메테우스 설정을 쿠버네티스 네이티브로 만듦

    3.8 로깅 개요

    • 쿠버네티스 감사 로그는 보안 모니터링 앱
    • 로그를 중앙레포지토리에 보내는 방법
      • 모든 애플리케이션 로그를 표준 출력으로 보내기
        • 통일된 방법으로 로깅 가능 → 모니터링 데몬은 도커 데몬으로 부터 직접 로그 수집
      • 사이드카 패턴
        • 쿠버네티스 파드 안의 애플리케이션 컨테이너 옆에 로그를 전달하는 컨테이너를 실행

    3.10 EFK 스택을 사용한 로깅

    • 로깅 플랫폼이 관리하는 것이 정말 가치있는 일인지 잘 생각해보기

    3.11 알림

    • 즉각 대응할 필요 없는 알림 처리 방법
      • 자동으로 해결하도록 하기 (메모리 확보를 위한 로그 삭제, 생명성 프로브를 이용해서 응답없는 프로세스 자동 복원 등)
    • 5분 이하의 알림 임계치를 적절하게 설정하여 거짓 알림을 최소화

     

     

     

     

     

     

    Ch4. 설정, 시크릿, RBAC

     

    4.1 컨피그맵과 시크릿을 통한 설정

    • 쿠버네티스는 configmap과 secret resource를 이용해서 설정정보 전달
      • 파드가 수신 정보를 저장하는 방식과 데이터가 etcd에 저장되는 방식이 다르다

    4.1.1 ConfigMap

    • 설정 정보를 파드에 전달 및 컨트롤러, CRD, 오퍼레이터 등 복잡한 시스템 서비스로도 정보를 제공
    • 대상 : 민감하지 않은 문자열 데이터
    • 파드에 볼륨을 마운트 하거나 환경 변수로 전달

    4.1.2 Secret

    • 시크릿 데이터는 보이지 않게 저장되고 처리되어야 함
      • Base64로 인코딩 된 정보로 표현되는데, 암호화 되지 않음
      • 타입
        • generic : 일반적 키/값 쌍
        • docker-registry : 개인 도커 레지스트리 인증에 필요한 신원, image Pullsecret에서 이 신원을 저장하면 kubelet이 파드 템플릿으로 전달
        • tls : 공개/개인 키 쌍으로 전송 계층 보안(TLS) 시크릿을 생성
      • 시크릿은 자신을 사용하는 파드가 있는 노드의 tmpfs에만 마운트 됨
        • 파드가 종료될 때 시크릿은 삭제됨
      • 기본적으로 시크릿은 etcd 데이터 스토리지에 평범한 텍스트로 저장되어 보안에 신경써야함

    4.2 컨피그 맵과 시크릿 API 모범 사례

    • 새로운 버전의 파드를 재배포 하지 않고 동적 변경을 위해서는 컨피그 맵과 시크릿을 볼륨으로 마운트
      • 변경된 파일 데이터를 감지하고 필요에 따라서 재설정 하려면 애플리케이션을 파일 감시자로 설정
      • 볼륨마운트 사용시 컨피그맵/ 시크릿이 생성되자마자 파드 명세서에 볼륨을 추가해야하고, volumeMounts.subPath 속성을 사용해서 컨피그맵/ 시크릿을 마운트 하면 안된다.
    • Admission controller를 사용하여 특정 설정 데이터를 확인하고 특정 설정 값이 존재하지 않는 경우 배포를 막을 수 있음
    • 헬름을 사용하여 사용자 환경에 앱을 배포하는 경우 라이프 사이클 훅을 통해 Deployment를 적용하기 전에 컨피그맵, 시크릿 템플릿이 배포되었는지 확인해야 함
    • 일부 애플리 케이션은 JSON 이나 YAML 파일 등 단일 설정 파일로 만들어야 함
    • 시스템 환경 변수를 이용해서 컨피그 맵 데이터 주입 가능
      • envFrom, configMapRef or secretRef 통해 마운트
        • 이때, 부적합 하다고 간주되는 환경 변수값은 건너뛰지만 파드는 시작할 수 있음
    • configMapKeyRef 또는 secretKeyRef 방법을 사용할 때 실제 키가 존재하지 않는 다면 파드 시작 불가
    • 환경 변수 형태로 전달하는 경우 configmap/secret을 업데이트 하더라도 파드안의 값은 업데이트 되지 않음
      • 파드를 삭제하고 replicaSet controller가 새로운 파드를 생성하여 재시작하거나 적절한 애플리케이션 업데이트 전략을 Deployment 명세에 선언하고 Deployment 업데이트를 통해 재시작 해야함
    • 시크릿 모범 사례
      • 쿠버네티스보다 더 높은 수준의 암호화 및 감사기능을 제공하는 외부 스토리지 시스템 사용 가능
      • 파드가 자동 마운트를 하기 위해서 imagePull Secrets를 service account에 할당

    4.3 RBAC

    • 대규모 분산 환경의 경우 특정 보안 매커니즘을 통해 중요시스템에 대한 무단 접근을 방지
    • 대상 : 컴포넌트
      • 사용자와 그룹은 권한 모듈을 이용해 쿠버네티스에서 관리
    • 규칙
      • 특정 객체 또는 객체 그룹에 실행할 수 있는 기능 목록
      • 정의된 규칙을 적용할 범위
      • 롤바인딩을 통해 사용자, 그룹과 같은 대상을 특정 롤에 매핑 가능

    4.3.2 RBAC 모범 사례

    • 애플리케이션 코드가 실제로 쿠버네티스 API와 직접 상호작용할 때만 RBAC 설정 필요
    • 단기간 권한 상향이 필요한 사용자들이 구체적인 작업을 진행할 수 있도록 해야함
    • 배포될 CI/CD 도구를 위해 특정 서비스 계정을 사용해야함
    • 네임스페이스에 대한 범위가 지정된 틸러(기본 서비스 계정) 전용 서비스 계정을 사용하여 각 네임스페이스에 틸러를 배포하는 것이 좋음
    • 시크릿 API에 접근해야 한다면 직접 할당된 시크릿 이외의 것들에 대한 get 사용을 제한해야함
Designed by Tistory.