Victoree's Blog

[1] 쿠버네티스 오브젝트 본문

Infra/Kubernetes

[1] 쿠버네티스 오브젝트

victoree 2021. 5. 28. 15:26
728x90

Kubernetes 시작하기

Kubernetes 고유 특징

  1. 모든 리소스는 오브젝트 형태로 관리

    • 아래 요소들을 모두 오브젝트라고 간주함
      • 서비스 : 컨테이너의 묶음
      • 파드(Pods) : 컨테이너의 집합
      • 컨트롤러(Replica Set) : 컨테이너의 집합을 관리하는 컨트롤러
      • 사용자(Service Account)
      • 노드(Node)
  2. 여러개의 컴포넌트로 구성

    • 쿠버네티스 노드
      • 마스터 : 클러스터를 관리
        • API-Server, 컨트롤러 매니저, 스케줄러, DNS Server, 프록시, 네트워크 플러그인
      • 워커 : 애플리케이션 컨테이너가 생성
    • kubelet : 클러스터 구성을 위한 에이전트

Pod : 컨테이너를 다루는 기본 단위

  • 컨테이너 어플리케이션의 기본 단위
  • 하나의 완전한 어플리케이션
  • 1개 이상의 컨테이너로 구성된 컨테이너의 집합
  • Docker -> 도커 컨테이너 / 스웜 모드 -> 서비스 / 쿠버네티스 -> 파드
  • 1개의 포드에서는 1개의 컨테이너가 있을 수도 있고, 여러개의 컨테이너가 존재할 수도 있음

yaml 파일 구조

  • apiVersion : 오브젝트의 API 버전을 나타냄
  • kind : 리소스의 종류
    • 리소스 오브젝트인 pod나 pvc, pv등을 입력함
  • metadata : 라벨, 주석, 이름 등과 같은 리소스 부가정보를 입력함
  • spec : 리소스 생성을 위한 자세한 정보 입력
    • containers 하위에 name(컨테이너 이름), image(사용할 도커 이미지), ports(사용할 컨테이너 포트)를 입력할 수 있음

kubectl apply -f 명령어로 쿠버네티스에 생성할 수 있음

포드 v.s. 도커 컨테이너

  • 포드 또한 ip주소를 가지고 있어 클러스터 내부에서 접근 가능
  • kubectl exec 명령어로 포드 컨테이너 내부로 들어갈 수 있음
  • kubectl logs 명령어로 포드의 로그 확인가능
  • 도커 컨테이너 대신 포드라는 개념 사용 이유?
    • 여러 리눅스 네임스페이스를 공유하는 여러 컨테이너들을 추상화된 집합으로 사용하기 위함
    • 특정 포드에 여러 컨테이너를 넣을 수 있긴 함(잘 안함)
      • 명령어를 시행할 때 -c라는 옵션으로 컨테이너를 지정할 수 있음
      • 각 내부 컨테이너가 같은 네트워크 네임스페이스를 공유하는 등 같은 리눅스 네임스페이스를 공유해 사용함
        • 네트워크 네임스페이스
        • 컨테이너의 공유한 네트워크 환경을 제공해주는 역할
    • yaml의 command, args
      • command : 도커 컨테이너의 Entrypoint(가장 먼저 실행되는 파일)
      • args : dockerfile의 Cmd와 동일
    • 특정 파드 내에 두개 이상의 컨테이너가 있을 때
      • nginx 컨테이너가 실행되기 위해, nginx 설정파일의 변경사항을 갱신해주는 설정 리로더 프로세스 또는 로그 수집해주는 프로세스는 nginx 컨테이너와 함께 실행되야 함
      • 주 컨테이너와 서브 컨테이너를 함께 포드에 포함시킬 수 있음
      • 부가적인 컨테이너 -> 사이드카 컨테이너
        • 동일한 네임스페이스들을 공유하여 사용할 수 있음

Replica Set : 일정 개수의 포드를 유지하는 컨트롤러

Replica Set 사용 이유

  • 포드의 생애주기 관리
  • 동일한 여러개의 포드를 생성한 뒤, 외부 요청이 각 컨테이너에 적절히 분배(로드 밸런서처럼)
    • 이름만 다른 동일 파드를 yaml에 ---로 구분하여 원하는 수만큼 띄워둠
      • 비효율적인 방법
      • 삭제되거나, 해당 노드에 장애가 발생하여 접근하지 못하게 됨 -> 직접 포드 삭제 후 재생성해야함

Replica Set 동작 원리

  • 정해진 수의 동일한 포드가 항상 실행되도록 관리함
  • 노드 장애 등의 이유로 포드를 사용할 수 없다면, 다른 노드에서 포드를 다시 생성함

    spec.replicas : 동일한 포드를 몇개 유지시킬지 설정
    spec.template : 포드 생성시 사용할 템플릿
    포드 사용내용을 동일하게 정의함으로 어던 포드를 어떻게 생성할지 명시

  • 레플리카셋을 삭제하거나 수정 시 포드에 변경사항이 반영됨
    • yaml파일에 replicas를 3 -> 4로 해도 바로 변경사항이 반영됨
    • kubectl apply -f yaml 하면, Created가 아닌 configured가 출력되며, 기존 리소스가 수정됨
    • kubectl delete -f || rs yaml 하면, 해당 레플리카가 삭제됨
      • 레플리카셋에 의해 생성된 포드도 함께 삭제됨
        • 하지만 레플리카셋이 포드와 연결되어 있는 것은 아님
  • 라벨 셀렉터에 의해 레플리카셋과 포드는 느슨한 연결 상태를 유지하고 있음
    • 쿠버네티스 리소스의 부가 정보 표현
    • 서로 다른 오브젝트가 서로를 찾아야 할때 사용
      • 생성해야 하는 포드를 찾음
    • 해당 라벨을 가지는 포드의 개수가 replicas의 수치와 일치하지 않으면 pod templete 항목으로 포드를 생성함
    • $ kubectl get pods --show-labels

Deployment: 레플리카셋, 포드의 배포를 관리

Deployment란?

  • 레플리카셋의 상위 오브젝트
  • 컨테이너 어플리케이션을 배포하고 관리하는 역할
  • 포드와 레플리카셋을 직접 생성할 필요가 없음
    • 실행하면 레플리카셋과 레플리카 수에 따른 파드 n개가 생성됨
  • $ kubectl apply -f <yaml파일>로 적용하고, $ kubectl get deploy || deployment로 배포할 수 있음
  • 디플로이먼트 삭제 시, 이에 종속된 파드와 레플리카셋도 삭제됨

Deployment 사용 이유

  • 어플리케이션의 업데이트와 배포를 더욱 편하게 만들기 위함
  • 어플리케이션을 업데이트할 때, 레플리카셋의 변경 사항을 저장하는 리비전(revision)을 남겨 롤백을 가능하게 해줌
    • $ kubectl set image deployment <deployment_name> nginx=nginx:1.11 --record
    • 파드를 업데이트 시킬 때, 이미지를 업데이트 시키면 새롭게 생성된 파드들이 존재함
      • Pod도 이전 set이 존재하는 것 같지는 않음
    • 이전에 사용한 replica set을 삭제하지 않고 남겨둠 -> 리비전으로 보존함
      • $ kubectl rollout history deployment <deployment_name>
    • undo를 통해 롤백할 수도 있음
  • 무중단 서비스를 위해 파드의 롤링업데이트의 전략을 지정할 수 있음

Service : 파드를 연결하고 외부에 노출

Service의 기능

  • 포드에 접근하기 위한 규칙 정의
  • 여러개의 포드에 쉽게 접근할 수 있도록 고유한 도메인 이름을 부여함
  • 여러 개의 포드에 접근할 때, 요청을 분산하는 로드 밸런서 기능을 수행함
  • 클라우드 플랫폼의 로드 밸런서, 클러스터 노드의 포트 등을 통해 포드를 외부로 노출함
  • $ k get pods -o wide로 파드의 IP 확인가능함
  • 파드에 어떻게 접근할 것인지에 따라 종류가 여러개
    • ClusterIP 타입
      • 쿠버네티스 내부에서만 포드에 접근할 때 사용
      • 외부로 파드를 노출하지 않음
    • NodePort 타입
      • 파드에 접근할 수 있는 포트를 클러스터의 모든 노드에 동일하게 개방
      • 외부에서 포드에 접근 가능
      • 접근할 수 있는 포트는 랜덤으로 정해지나, 특정 포트로 접근하도록 설정할 수도 있음
    • LoadBalancer 타입
      • 클라우드 플랫폼에서 제공하는 로드 밸런서를 동적으로 프로비저닝해 포드에 연결
      • 외부에서 포드에 접근 가능
      • AWS, GCP 와 같은 클라우드 플랫폼 환경에서만 사용가능
  • 서비스를 생성할 때, 별도의 설정없이도 연결된 포드에 대해 로드 밸런싱을 수행함
  1. ClusterIP web-port
  • 쿠버네티스 내부에서만 포드에 접근할 수 있는 포트

    spec:

    ports:

    • name: web-port

      port: 8080

      targetPort: 80

      selector:

      app: webserver

      type: ClusterIP
  • spec.selector : 어떤 라벨의 포드에 접근할 지 결정

  • spec.ports.port : 서비스의 IP에 접근할 때 사용할 포트

  • spec.ports.targetPort : containerPort 항목에서 사용할 포트를 동일하게 설정해야 함

  • 포드가 서로 상호작용해야 할 때, 포드의 IP를 몰라도됨

    • 서비스 이름을 사용함으로 접근 가능
  1. NodePort
  • 모든 노드의 특정 포트를 개방해 서비스에 접근하는 방식
  • $ kubectl get service를 통해 포트를 확인할 수 있음
  • YAML 파일에 nodePort항목을 지정하여 포트를 선택할 수도 있음
    • 너무 낮은 포트의 경우, 시스템에 의해 예약된 포트로 사용불가능 할 수 있음
  • 보통 실서비스에서는 노드포트로 서비스를 외부로 직접 제공하기 보다 Ingress라는 오브젝트로 간접 사용됨
  1. LoadBalancer
  • 동적으로 생성하는 기능을 제공하는 환경에서 사용할 수 있음 (GCP, AWS)
  • $ kubectl get service를 하면 EXTERNAL-IP 항목을 볼 수 있음
728x90

'Infra > Kubernetes' 카테고리의 다른 글

[2] Kubernetes 리소스의 관리와 설정  (0) 2021.05.28
Comments