개발 기술 블로그

Kubernetes Service - MetalLB

  • 온프레미스 클러스터는 Load Balancer를 구매하지 않는 한 부하분산 기능 및 외부연결용 IP 제공하는 리소스가 필요
  • MetalLB는 Bare Metal 환경(가상화 하지 않고 사용하는 고성능 물리 서버)에서 사용 할 수 있는 Load Balancer 기능을 제공(CNCF 오픈소스 프로젝트)
  • MetalLB는 네트워크 로드 밸런서를 통해 “외부 IP 주소 풀"을 사용하여 온프레미스 및 VM등의 가상 환경 클러스터에서 외부 서비스 접근 가능

  • 온프레미스 환경에서 Service “type:LoadBalancer"의 EXTERNAL-IP <pending> 할당
  • Load Balancer IP로 전달되는 트래픽을 Node로 전달 하면 MetalLB의 역할은 끝남
  • 제공되는 서비스 IP(EXTERNAL-IP)는 ping 작동 안되며 서비스에 대한 동작은 제공된 IP를 통해 애플리케이션에 액세스하여 확인 가능
  • Layer2 mode (링크)
    • 클러스터 노드 중 하나(리더 노드)가 외부에서 접속 가능한 IP의 ARP request를 네트워크 인터페이스에서 할당처리
      • ARP(Address Resolution Protocol)? IP주소를 MAC주소와 매칭 시키기 위한 프로토콜
    • 구성이 단순하여 대용량 처리에 부하가 심하여 테스트용으로 권장
  • BGP mode (링크)
    • 고가용성이 구성가능하여 운영환경에서 주로 사용
  • Controller(Deployment)
    • 구성된 IP pool에서 로드 밸런싱을 수행할 EXTERNAL_IP 주소를 할당하는 역할
  • Speaker(DaemonSet)
    • Layer2 or BGP모드를 통해 할당된 IP를 알리는 역할 수행
      • speak pod는 node IP를 사용
  • 서비스 계정(컨트롤러 및 스피커)
    • 서비스 계정은 컨트롤러 및 스피커 구성요소 작동에 필요한 RBAC 사용 권한이 포함
  • 사용할 IP 주소의 대역 설정을 통해 IP제공
  • 설치 후 필수 → “EXTERNAL_IP 대역”, “설정 모드” 지정을 위한 configmap 배포
  • Node NIC에 IP를 바인딩 하지 않고 로컬 네트워크의 ARP 요청에 응답하여 컴퓨터의 MAC주소를 클라이언트에게 제공하는 방식으로 작동
  • LoadBalancer 생성 → MetalLB L2 Controller는 APIserver를 통해 EXTERNAL-IP를 리더 Speaker pod에 할당 → Speaker pod는 소유하고 있다는 것을 ARP를 이용해 모든 노드 Speak Pod에 전파

Kubernetes Service (ClusterIP, NodePort, LoadBalancer)

Service는 네트워크 추상화 object로 생성된 Pod에 동적접근 및 이를통하여 Application을 cluster내의 네트워크 서비스로 노출 할 수 있으며 IP 주소 또는 DNS이름을 통해 특정 포트에 직접 액세스 할 수 있도록 Pod를 논리적 그룹화가 가능하다. 또한 Pod집합에 대한 단일 DNS명을 부하하여 분산을 수행 할 수있다.

    1. Pod에 문제가 생기면 Kubernetes는 그 Pod를 삭제 후 재생성 한다.
    1. 이때 기존 Pod IP가 같을 확률은 매우 낮다.(Kubernetes 설계 사상: App를 유지 목적, Pod는 언제즌 장에에 의해 Down 될 수 있고 재시작 될 수 있다. )
    1. IP가 새로이 부여 될때마다 Application을 매번 수정해야하는 불편함을 없애기 위해 Service 사용하게 설계되었다.
  • 클라이언트에서 내부에 있는 Pod Application 접근을 위한 단일 진입점 역할을 하며 Proxy(Load Balancer)처럼 연결된 Pod들에 트래픽을 전달하는 object(Servece object)로 Clien요청 트래픽을 각각의 Pod로 포워딩한다.
  • 가상IP와 port를 가지고 생성
  • Kube-proxy를 통해 Service의 가상IP, port를 관리
  • Service object는 Pod를 트래픽에 노출, Endpoint object는 Pod IP, port가 존재
    • 트래픽 ↔ Service object ↔ Endpoint object ↔ IP, port 를 이용하여 Pod 특정
  • Service를 사용하여 Pod를 노출하면 kube-proxy는 Service를 통하여 그룹화된 Pod로 트래픽을 보내는 네트워크 규칙(Rules)생성
    • kube-proxy → Service(Pod:nginx1, Pod:nginx2, Pod:nginx3)
  • kube-proxy는 Service 변경사항 및 Endpoint 모니터링(변경사항)하여 트래픽을 Routing 하기 위한 규칙을 설정된 Mode를 사용하여 생성 및 업데이트 한다
    • Iptable mode(기본): kube-proxy는 iptabels를 관리하는 역할만 수행(트래픽 X), 모든 요청은 iptable를 거쳐 pod로 직접 전달
    • IPVS mode(IP Virtual Server): Netfilter Framework 기반으로 구현된 LInux kernel Level에서 동작하는 Layer4 Load Balancing 도구(모듈: RR, LC, DH, SH, SEC)
    • round-robin
    • least connection
    • destination hashing
    • source hashing
    • shortest expected delay
  • kube-proxy는 DaemonSet object type으로 모든 노드에서 실행

  • 서비스의 정보를 보기위하여 사용

Kubernetes StatefulSet

읽기전 Volume PV&PVC 와 Volume StorageClass먼저 읽어 볼 것

  • 애플리케이션의 statefulSet을 관리하는 workload 리소스

  • Stateless 애플리케이션은 Deployment로 배포하고, Stateful인 DB 같은 경우는 StatefulSet로 배포

  • StatefulSet으로 실행시킨 Pod는 Deployment(deploy-app-5skdw)와 다르게 pod-0, pod-1과 같은 순서값과 안적적인 네트워크 ID를 Pod에 할당

  • Pod는 오름차순으로 생성되고, 다음 Pod는 이전 Pod가 준비되고 실행상태가 된 후에만 생성, 삭제는 큰 수의 Pod부터 삭제됨 → “OrderedReady”

  • Pod를 순서없이 병렬로 실행되거나 종료 시킬려면 “Parallel” 사용(spec.podManagemetPolicy: “Parallel”)

    • kubectl explain statefulset.spe.podManagementPolicy
  • StatefulSet의 각 Pod들은 동일 spec으로 생성되지만 서로 교체는 불가능. 즉 re-scheduling이 되도 지속적으로 동일 식별자 유지

Kubernetes Volume - NFS

  • Kubernetes는 Storage Volume 정의를 통해 Pod의 Volume을 정의한다
  • Pod컨테이너 내에 저장된 파일은 별도 설정이 없으면 Host의 임시 디스크에 보관
    • Pod 삭제 및 재시작 시 임시 디스크의 데이터 함께 소실
    • 멀티 컨테이너 Pod는 내부 컨테이너 간 데이터 공유 수행 필요
    • Volume 추상화는 이러한 문제를 해결하는 매커니즘을 제공
    • Volume은 Pod.spec에 포함하여, Pod내 filesystem에 mount됨
      • Pod.spec → .spec.volumes 구문으로 볼륨기술 및 이름 지정
      • .spec.containers[*].volumeMounts. 컨테이너 내부 FS에 mount → df -h 확인
      • 데이터 공유 및 지속성, API 기능을 통한 데이터 이전효과 지원

임시 volume

Kubernetes Volume - PV & PVC

  • PV object로 Storage를 추상화하고 PVC object로 Storage를 할당받아 사용
  • PV(Persistent Volume)는 관리자나 StorageClass에 의해 생성되는 Volume
  • PVC(PV Claim)는 사용자가 Volume을 사용하기 위해 PV에 요청

  • PV를 만드는 단계
  • PV를 미리만들고 사용하는 정적(static)방법과 요청이 있을때 만드는 동적(dynamic)방법이 있다.
  • PV를 PVC와 연결하는단계
  • PVC는 스토리지 용량과 접근방법에따라 PV와 연결, 대응되는 PV가 없으면 대응되는 PV가 생성될때까지 Pending
  • PV와 PVC는 1:1 관계
  • Pod에서 PVC를 통해 PV의 볼륨으로 인식하고 사용하는 단계
  • 사용이 끝난 PVC가 초기화 되는 단계
    • Retain: PVC 삭제 → PV Status(bound → Released)로 바뀌며 다른 PVC가 연결 될 수 없는 상태. PV 속 데이터는 유지
    • Delete: PVC 삭제 → PV 삭제
    • Recycle: PVC 삭제 → PV Status(bound → Pending)로 바뀜, 다른 PVC 대기
  • PV 생성시 설정하는 접근 권한
    • ROX(ReadOnlyMany) - 읽기만 가능, 모든 노드 접근 가능
    • RWX(ReadWriteMany) - 읽기, 쓰기, 모든 노드 접근 가능
    • RWO(ReadWriteOnce) - 읽기, 쓰기, 단일노드

PV123.yaml

Kubernetes Volume - StorageClass

  • 관리자가 수동으로 PV생성
  • 하위 세부요소인 용량, 액세스 도드 및 저장소 유형을 지정
  • 정의된 PV는 사용자가 생성하는 PVC의 요구사항과 일치하는 사용 가능한 PV에 Binding
  • PVC요청에 맞게 PV생성을 자동화
  • 관지라는 PV 생성하기 위한 템플릿 StorageClass 정의
  • 사용자가 특정 StoargeClass를 참조하는 PVC를 생성하면 프로비저너는 PVC요구사항에 맞는 PV를 자동 생성
  • 프로비저너(Porvisioner)는 일반적으로 CSP가 제공하는 볼륨플러그인을 사용
  • 운영환경에서는 성능을 최대로 높게
  • 개발환경에서는 느리지만 안전한 volume에 저장하도록 구성
  • 운영정책에 따라 StorageClass를 정의하여 그에 맞는 PV를 자동 생성 가능
  • OpenEBS hostpath는 Pod가 실행되는 Node의 디렉토리(hostpath)를 Pod의 볼륨으로 할당

Kubernetes 설치 (containerd, kubelet, kubeadm, kubectl)

  • docker → image 개발 및 테스트
  • containerd → Kubernetes에서 사용하는 container runtime
    • docker runtime 주의
      • Docker와 containerd가 모두 감지되면 Docker가 우선
      • 두 개 이상의 런타임이 감지되면 kubeadm은 오류와 함께 종료
  • Kubernetes(kubelet kubeadm kubectl)
    • kubelet → Kubernetes간 통신
    • kubeadm → 관리
    • kubectl → commend

Kubernets 클러스터 환경 구축시는 초기화, CNI도 추가로 진행해야 함

Kubeshark - 트래픽 분석 도구

컨테이너, 포드, 노드 및 클러스터에 들어오고 나가는 모든 트래픽과 페이로드를 캡처하고 모니터링하는 API 트래픽 분석기

  • 내부 네트워크에 대한 실시간 프로토콜 가시성 제공
  • eBPF를 통해 구현, 커널 공관과 유저 공간의 모니터링을 통해 인사이트 제공
  • kprobe를 사용해 TCP 커넥션에 대한 정보(Source, Destination IP Port)를 수집(Trace)하여 Request/Reponse를 하나로 묶어 제공
  • 실제 TCP 패킷은 PCAP 파일로 임시 저장하여 다운로드 가능
  • TLS로 암호화된 패킷은 평문으로 확인 가능
  • 통신 간 발생하는 Request, Reponse Header 확인을 통한 애플리케이션 인증 문제확인
  • Network, Memory 자원을 많이 사용하므로 ks tab 명령 사용 시 대상을 정확히 지정하여 trace 하는 것을 권장
    • ex : ks tab -n default “(calico* | myweb*)”

Pod - Init Container

  • Application container이전에 실행되는 특수 컨테이너 → app.Container 실행환경 준비
  • 다양한 목적으로 사용 가능하지만 Application container 가 원하는 방향으로 실행 될수 준비하는것이 주목적 →메인프로세스 환경의 초기화
  • App.Container 소스코드 변경 할 필요 없이 환경을 구성가능하게 함
  • Pod에 관련된 모든 네트워킹 및 스트리지가 프로비저닝 된 후에 실행
  • Pod의 initial container가 실피시 kublet은 성공 할 때 까지 init.Container를 반복적으로 재시작
  • 단, Pod restartPolicy: Never가 지정되었을땐, init.Container가 실패하면 Kubernetes는 전체 Pod를 실패 처리 후 종료
  1. MSA 소스로부터 최신 구성 파일을 가져오는 작업 → App.Container는 항상 최신 구성이 가능 해짐
  2. DB init 또는 초기(기본) 데이터를 채우는 작업 구성(스키마 생성, 데이터 마이그레이션)을 처리하여 DB가 App.Container와 상호 작용 준비가 되었는지 확인 할 수 있음 → App.Container 경량화
  1. Local volume 영역을 생성
  2. Init.Container는 curl로 외부 리소스를 받아 해당데이터를 Local volume에 기록
  3. App.Container는 시작과 함게 Local volume에서 필요한 데이터를 읽어 작동