본문 바로가기
쿠버네티스

쿠버네티스 개념 및 용어 정리

by 초특급하품 2022. 2. 20.

쿠버네티스를 이해하기 위해 클러스터, 노드 수준의 큰 그림부터 시작해서 pod, service, ingress 등의 개념까지 짧게 정리했다. 돌아가는 수준으로 이해하기는 쉽지만 역시 잘 쓰기 위해서는 알야할 개념들이 훠어어얼씬 많다.

 

마스터 / 노드

쿠버네티스의 각종 개념들은 결국 노드에서 실행되는데 역할에 따라 마스터와 노드로 나뉜다.

마스터 (control plane)

쿠버네티스 클러스터를 관리해서 요구조건에 맞는 상태가 유지되도록 한다.

kube-apiserver

  • 마스터의 프론트엔드로 모든 요청을 받아 해석하고 아래 컴포넌트들과 유기적으로 동작한다.
  • 예를 들어 pod 생성 요청이 온 경우
    1. 요청 문법을 검사한다. 
    2. etcd에서 노드 상태를 가져다가 scheduler에게 어떤 노드에 띄울지 물어본다.
    3. 어디에 띄울지 정보를 받은 후 해당 노드의 kubelet에게 실행 명령을 전달한다.
    4. 해당 노드의 kubelet가 컨테이너 실행을 명령한다.

etcd

  • 워커노드 kubelet에서 보낸 노드 상태를 고가용성을 보장하며 key-value로 저장한다.

kube-controller-manager

  • 노드, pod, service 등을 모니터링하여 요구된 명세와 현재 상태가 같도록 유지시킨다.

kube-scheduler

  • 노드 상태(hw/sw, 리소스, 요구 사항 등)를 확인해서 pod를 어떤 노드에 띄울지 선택한다.

 

노드

kubelet

  • 노드에 배포되는 agent
  • pod에 container가 동작하도록 관리한다.
  • cAdvisor가 탑재되어 노드 리소스를 수집하고, 이 정보를 마스터 노드 apiserver에 보낸다.

kube-proxy

  • 아래 설명할 service를 구현한 프록시로 노드로 들어오는 트래픽을 적절한 컨테이너로 라우팅한다.

container runtime

  • pod에 배포된 컨테이너를 실행하는 런타임
  • 도커 외에 rkt, hyper container 등 런타임이 있다.

이렇게 마스터 / 노드 장비가 준비되었으면 서비스를 돌리기 위한 최소한의 단위인 pod을 만들어서 쿠버네티스에 올릴 준비가 완료됐다.

 

 

Pod

nginx-pod.yaml 파일 생성

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    run: nginx-pod
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80

실행

$ kubectl create -f nginx-pod.yaml

 

pod 내부는 container 여러 개로 구성된다.

  • 각 container는 localhost로 통신 가능하다.
  • pod 기동 시 디폴트로 생성되는 볼륨은 재기동시 사라진다. persistent volume으로 pod 생명주기를 넘어 유지시킬 수 있다.
  • 디스크 볼륨 공유하기 때문에 사이드카 패턴으로 로그 수집, 모니터링 할 수 있다.

kind: Pod으로 단일 pod을 생성할 수 있지만 고가용성과 scale out을 위해 여러 pod을 안정적으로 제공하기에는 부족하다. 여러 pod 묶음을 안정적으로 유지시키는 컨트롤러 개념이 등장한다.

 

 

컨트롤러

replication controller

  • 지정된 숫자로 pod이 떠있도록 관찰하고 유지한다.
  • replica / selector / pod template을 명시한다.
  • template에서 pod 배포 명세와 같은 템플릿을 작성한다.

replica set

  • apiVersion이 v1에서 apps/v1으로 변경된다.
  • replication controller에 풍부한 selector 기능이 추가된다.
    • matchLabels(기존 selector)
    • matchExpressions: In, NotIn, Exists, DoNotExist 등의 operator를 사용할 수 있다.

deployment

  • repelica set에 배포 전략이 추가된다.
  • 새로운 replica set을 생성하고 두 replica set의 replica 개수를 조절하면서 배포한다.
  • kubectl rollout undo revision을 지정하면 롤백된다.
  • nginx-deployment.yaml 파일 생성
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
  matchLabels:
    app: nginx-pod
  template:
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
      - image: nginx
        name: nginx
        ports:
        - containerPort: 80

실행

$ kubectl create -f nginx-deployment.yaml

 

daemon set

  • 모든 노드 또는 라벨 지정한 노드에 pod를 하나씩 띄우는 컨트롤러
  • 로그 수집, 모니터링 등에 쓴다.

job

  • 한번 실행되고 죽는 워크로드
  • 실패하면 재시도할지, 몇 번 반복할지, 병렬로 실행할지 옵션

cron job

  • cron + job
  • concurrencyPolicy로 동시에 실행 가능 여부를 설정한다.

stateful set

  • pod 이름 보장한다.

이렇게 컨트롤러를 통해 여러 개의 pod가 떠있도록 보장했다. 이제 이렇게 보장된 pod들에 요청하기 위해 단일 진입점을 만들어야 한다.

 

 

Service

nginx-service.yaml 파일 생성

apiVersion: v1
kind: Service
apiVersion: v1
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

실행

$ kubectl create -f nginx-service.yaml

 

service는 여러 pod을 묶어서 앞단에 로드밸런서를 배치하여 하나의 virtual ip를 제공한다. pod가 추가/제거되거나 재기동되어 ip가 변경되어도 service가 pod ip 정보를 수집해서 갱신한다. 타겟이 되는 pod는 label selector로 지정한다.

service type

cluster ip

  • 클러스터 내부에서만 사용 가능한 내부 ip를 생성한다.

node port

  • clusterIp 기능을 포함한다.
  • 모든 노드에 port(30000-32768)가 추가되어 노드로 직접 접근 가능하고, 이를 다시 로드밸런싱 한다.

load balancer

  • node port 기능을 포함한다.
  • provider에서 제공하는 l4 로드밸런서가 생성되고 외부에서 접근 가능한 external ip 제공한다.

external name

  • 위 타입과 전혀 다른 기능이다.
  • 내부에서 외부로 나갈 수 있는 dns 기능으로 servicename 도메인을 원하는 도메인으로 포워딩한다.

headless service

  • 실제로 type으로 명시되는 건 아니고 clusterIp: None으로 생성된 서비스를 칭한다.
  • pod endpoint들을 모아서 coreDns까지 저장한다.

이렇게 단일 진입점까지 만들었으니 안정적으로 서비스를 돌릴 수 있다. 그렇지만 애플리케이션이 커져서 컴포넌트가 늘어가면 이에 따라 서비스도 늘어나게 된다. 여러 서비스 앞단에 로드밸런서를 두어 이를 해결할 수 있다. 이를 쿠버네티스에서는 ingress라고 부른다.

 

 

Ingress

l7 로드밸런싱으로 url path 기반으로 라우팅 한다. path별로 service name을 지정하고, 기본값으로 연결할 수도 있다.

여러 서비스들과 연결되는 로드 밸런스인 만큼 각 서비스 별로 health check 가 필요한데, 이 health check api는 pod 정의하는 곳에서 containers[].readinessProbe.httpGet 으로 정의한다.

 

nginx-ingress.yaml 파일 생성

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  defaultBackend:
    service:
      name: nginx-service
      port:
        number: 80

실행

$ kubectl create -f nginx-ingress.yaml

 

기본으로 연결된 서비스밖에 정의하지 않았지만 서비스별로 prefix를 나누어 아래와 같이 하나의 ingress controller로 전체 서비스를 운영할 수 있다.

전체 구성도

 

댓글