ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] 쿠버네티스 이해하기
    Engineering/DevOps 2022. 1. 15. 18:48
    반응형

    쿠버네티스 이해하기

    쿠버네티스란?

    • 쿠버네티스는 컨테이너 오케스트레이션을 위한 솔루션.

    컨테이너 오케스트레이션이란?

    • 다수의 컨테이너를 유기적으로 연결, 실행, 종료할 뿐만 아니라 상태를 추적하고 보전하는 등 컨테이너를 안정적으로 사용할 수 있게 유지시켜 준다.

    쿠버네티스 구성 요소


    참고 링크

    Master Node

    kubectl

    • 쿠버네티스 클러스터에 명령을 내리는 역할
    • 바로 실행되는 명령 형태인 바이너리로 배포되기 때문에 마스터에 있을 필요는 없음
    • 통상적으로 API Server 와 통신을 주로 함.

    API Server

    • 쿠버네티스 클러스터의 중심 역할을 함.
    • 모든 클러스터 컴포넌트의 상태를 추적하고, 컴포넌트들 사이의 상호작용을 매니징한다.
    • 수평적 확장이 가능하도록 설계되었다.
    • 클러스터로부터 요청이 왔을 때, 해당 요청의 유효성을 검증한다.

    etcd (key-value store)

    • 컴포넌트들의 상태 값을 저장하는 key-value 기반의 저장소이다.
    • 분산 저장이 가능하여 여러 곳에 저장해 두면 하나의 etcd 에서 장애가 발생하더라도 가용성을 확보할 수 있다.

    Controller Manager

    • 오브젝트들에 요구되는 상태들을 감시하고, 현재의 상태가 요구되는 상태로 적절히 유지되도록 관리한다.
    • 여러 종류의 컨트롤러가 존재한다.
      • Node Controller
        • 노드들이 다운되었을 때, 이를 알리고 응답하는 책임을 가지고 있다.
      • Job Controller
        • 계속해서 실행되어야 하는 성격이 아니라 실행되고나서 종료되어야 하는 성격의 작업을 실행시킬 때 사용하는 컨트롤러이다.

    Scheduler

    • 노드의 상태와 자원, 레이블, 요구 조건 등을 고려하여 파드를 어떤 워커 노드에 생성할 것인지를 결정하고 할당한다.

    Worker Node

    kubelet

    • 파드의 PodSpec 을 받아서 컨테이너 런타임으로 전달하고, 파드 안의 컨테이너들이 정상적으로 작동하는지 모니터링한다.
    • 클러스터의 모든 노드에서 실행된다.
    • API Server 와 노드 사이의 에이전트 역할을 한다.

    Container Runtime (CRI, Container Runtime Interface)

    • 파드를 이루는 컨테이너의 시작, 실행, 중지를 담당한다.
    • 파드 안에서 다양한 종류의 컨테이너가 문제 없이 작동하게 만드는 표준 인터페이스이다.

    Pod

    • 한 개 이상의 컨테이너로 단일 목적의 일을 하기 위해서 모인 단위.
    • 파드는 언제라도 죽을 수 있는 존재.

    옵셔널한 구성 요소

    Network Plugin

    • 쿠버네티스 클러스터 통신을 위해서는 네트워크 플러그인 선택하고 구성해야 한다.
    • 일반적으로 CNI(Container Network Interface)로 구성하고, 주로 캘리코(Calico), 플래널(Flannel), 위브넷(WeaveNet) 등을 사용한다.
    • CNI 는 구성방식과 지원하는 기능, 성능이 각기 다르므로 사용 목적에 맞게 선택하면 된다.
      • ex) Calico 는 L3로 컨테이너 네트워크를 구성하고, Flannel 은 L2로 컨테이너 네트워크를 구성한다.

    CoreDNS

    • 쿠버네티스 클러스터에서 도메인 이름을 이용해 통신하는 데 사용하는 DNS Server 이다.

    kube-proxy

    • 쿠버네티스 클러스터는 파드가 위치한 노드에 kube-proxy를 통해 파드가 통신할 수 있는 네트워크를 설정한다.
    • 실제 통신은 br_netfilter와 iptables로 관리한다.

    Lifecycle of pod

    1. kubectl을 통해 API Server에 파드 생성 요청
    2. API 서버에 전달된 내용이 있으면 API 서버는 etcd에 전달된 내용을 기록하여 클러스터의 상태 값을 최신 상태로 유지한다.
    3. API 서버에 파드 생성이 요청된 것을 컨트롤러 매니저가 인지하면 파드를 생성하고, 이 상태를 API 서버에 전달한다.
    4. API 서버에 파드가 생성됐다는 정보를 스케줄러가 인지하면, 시케줄러는 생성된 파드를 어떤 워커 노드에 띄울지 결정하고, 해당 워커 노드에 파드를 띄우도록 요청한다.
    5. API 서버에 전달된 정보대로 지정한 워커 노드에 파드가 속해 있는지 스케줄러가 kubelet으로 확인한다.
    6. kubelet에서 컨테이너 런타임으로 파드 생성 요청을 한다.
    7. 파드가 생성되고, 사용 가능한 상태가 된다.

    쿠버네티스는 절차적으로 진행하는 구조가 아니라 선언적인 시스템 구조를 가지고 있다.
    즉, 각 요소가 추구하는 상태를 선언하면 현재 상태와 맞는지 점검하고 그것에 맞추려고 노력하는 구조이다.
    (주기적으로 폴링을 하는건가?)


    쿠버네티스 기본 사용법 학습하기

    파드 구성 방법

    • kubectl run
    • > kubectl run nginx-pod --image=nginx # 위 명령을 통해 파드를 쉽게 생성할 수 있다 # nginx-pod 는 파드 이름 # --image=nginx 는 생성할 이미지 이름
    • kubectl get pod
      • kubectl get pod -o wide 명령을 통해 IP 정보, Node 등 파드에 대한 다양한 정보를 확인할 수 있다. 
      • > kubectl get pod # 생성된 파드를 확인한다
    • kubectl create
      • 위 명령을 통해서도 파드를 생성할 수 있다.
      • kubectl run 과 다르게 deployment 를 붙여야 한다.
      • 파드의 이름을 dpy-nginx 로 지정했지만 아래의 결과 화면에서 보이듯이 뒤에 무작위 문자열이 이름 뒤에 붙여져 있는 것을 확인할 수 있다.
        > kubectl create deployment dpy-nginx --image=nginx 

    run 과 create 는 무슨 차이?

    • run 으로 파드를 생성하면 단일 파드 1개만 생성되고 관리된다.
    • deployment 로 파드를 생성하면 디플로이먼트(deployment) 라는 관리 그룹 내에서 파드가 생성된다.

    오브젝트(Object)

    • 쿠버네티스를 사용하는 관점에서 파드와 디플로이먼트는 스펙(spec)과 상태(status) 등의 값을 가지고 있다.
    • 이러한 값을 가지고 있는 파드와 디플로이먼트를 포함해 부르는 단위를 오브젝트라고 한다.

    기본 오브젝트

    • 파드(Pod)
      • 쿠버네티스에서 실행되는 최소 단위이다.
      • 독립적인 공간과 사용 가능한 IP를 가지고 있다.
      • 하나의 파드는 1개 이상의 컨테이너를 가진다.
    • 네임스페이스(Namespace)
      • 쿠버네티스 클러스터에서 사용되는 리소스들을 구분하여 관리하는 그룹이다.
        • default: 특별히 지정하지 않으면 할당된다.
        • kube-system: 쿠버네티스 시스템에서 사용된다.
        • metallb-system: 온프레미스에서 쿠버네티스를 사용할 경우 외부에서 쿠버네티스 클러스터 내부로 접속하게 도와주는 컨테이너들이 속해 있다.
    • 볼륨(Volume)
      • 파드가 생성될 때 파드에서 사용할 수 있는 디렉터리를 제공한다.
      • 기본적으로 파드는 영속되는 개념이 아니라 제공되는 디렉터리도 임시로 사용하지만, 파드가 사라지더라도 저장과 보존이 가능한 디렉터리를 볼륨 오브젝트를 통해 생성할 수 있다.
    • 서비스(Service)
      • 파드는 클러스터 내에서 유동적으로 생성되고 파괴되기 때문에 접속 정보를 유지할 수 있도록 서비스를 통해 내/외부로 연결된다.
      • 서비스는 새로 파드가 생성될 때 부여되는 새로운 IP를 기존에 제공하던 기능과 연결해 준다. (서비스 디스커버리)
    • 디플로이먼트(Deployment)
      • 디플로이먼트는 애플리케이션 배포의 기본 단위가 되는 리소스이다.
      • 파드에 기반을 두고 있으며, 레플리카셋 오브젝트를 합쳐 놓은 형태이다.
      • 레플리카셋은 파드의 개수를 관리 및 제어하는 리소스이고, 디플로이먼트는 리플리카셋을 관리한다.
      • 레플리카셋은 레플리케이션 컨트롤러(ReplicationController)에서 발전한 형태이다.
      • 실제로 API 서버와 컨트롤러 매니저는 단순히 파드가 생성되는 것을 감시하는 것이 아니라 디플로이먼트처럼 레플리카셋을 포함하는 오브젝트의 생성을 감시한다.

    디플로이먼트는 왜 쓰는거지?

    • 레플리카셋은 단순히 파드 수를 보장하는 기능만 제공한다.
    • 롤링 업데이트 기능 등이 추가된 디플로이먼트를 사용하여 파드 수를 관리하면 스케일 인/아웃을 하기 수월하다
      > kubectl scale deployment dpy-nginx --replicas=3

    스펙을 지정해 오브젝트 생성해보기

    apiVersion: apps/v1 # API 버전
    kind: Deployment # 오브젝트 종류
    metadata:
      name: echo-hname
      labels:
        app: nginx
    spec:
      replicas: 3 # 몇 개의 파드를 생성할지 결정
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: echo-hname
            image: sysnet4admin/echo-hname # 사용되는 이미지
    • 위 스펙을 보면 어떤 컨테이너를 생성할 지에 대한 스펙이 정의되어 있다.
    • selector 를 통해 레이블을 지정하여 레플리카 수 만큼 파드를 생성한다.
    • kubectl create -f yaml_file.yaml 을 통해 해당 스펙을 실행시킬 수 있다.
    • spec yaml 을 수정하여 이미 생성된 기존의 deployment 를 수정하기 위해서는 kubectl apply 명령을 실행한다.
      • kubectl apply -f yaml_file.yaml

    디플로이먼트 삭제

    • kubectl delete deployment name
      • 디플로이먼트에 속한 파드는 상위 디플로이먼트를 삭제해야 파드가 삭제된다.
        > kubectl delete deployment echo-hname

    노드 자원 보호하기

    • 쿠버네티스는 모든 노드에 균등하게 파드를 할당하려고 한다.
    • 문제가 생길 가능성이 있는 노드인 경우 cordon 명령을 통해 해당 노드에 스케줄링 되지 않도록 대상에서 제외 시킬 수 있다.
      > kubectl cordon nodeName # 해당 노드에 파드가 스케줄링 되지 않도록 한다.
      > kubectl uncordon nodeName # 해당 노드에 스케줄링 되지 않도록 설정했던 것을 해제한다.

    노드 유지보수 하기

    • drain은 지정된 노드의 파드들을 모두 삭제하고 다른 노드에 다시 생성합니다.
    • 파드들을 모두 삭제하고, 다른 노드에 새로 생성하는 것이기 때문에 데몬셋이 존재하는 경우 drain으로 삭제할 수 없다.
      • --ignore-demonsets 옵션을 함께 사용하면 데몬셋을 무시하고 명령을 수행한다.
        > kubectl drain nodeName
        > kubectl uncordon nodeName # 해당 노드에 비활성화된 스케줄링을 다시 활성화 시킨다.

    파드 업데이트하기

    • --record 옵션으로 배포한 정보의 히스토리를 기록할 수 있다.
    • --record 옵션으로 기록된 히스토리는 rollout history 명령으로 확인할 수 있다.
    • > kubectl apply -f rollout-nginx.yaml --record > kubectl rollout history deployment rollout-nginx
    • set image 명령으로 파드의 컨테이너 버전을 업데이트 할 수 있다.
    • > kubectl set image deployment rollout-ngingx nginx=nginx:1.16.0 --record
    • describe 명령으로 쿠버네티스의 상태를 살펴볼 때 유용하다.
    • > kubectl describe deployment rollout-nginx

    파드 업데이트 실패 시, 복구하기

    • rollout undo 로 명령 실행을 취소하면 마지막 단계에서 전 단계로 상태를 되돌린다.
    • --to-revision 옵션을 사용하면 특정 버전의 상태로 복구할 수 있다.
      > kubectl rollout undo deployment rollout-nginx --to-revision=1
      > 

    참고자료

    컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커

    https://kubernetes.io/ko/docs/concepts/services-networking/service/

    반응형

    댓글

Designed by Tistory.