Kubernetes Pod 배치전략, NodeSelector에 대해 이해하고 실습해보기

Bakumando·2022년 5월 28일
0

Kubernetes

목록 보기
15/17
post-thumbnail

들어가기에 앞서...


0. 블로깅 목적

  • minikube로 멀티노드 클러스터 구성을 이해하고 실습한다.
  • Pod 배치전략 중 NodeSelector에 대해 이해하고 실습한다.

1. minikube로 멀티노드 클러스터 구성을 이해하고 실습한다.

1) minikube 클러스터에 멀티노드 구성

  • minikube는 멀티 노드 클러스터를 지원한다.
  • 싱글 노드로 생성된 minikube 클러스터는 기본적으로 CNI(Container Network Interface) 플러그인을 설치하지 않아, 해당 상태에서 노드를 추가한다고 해도 Network 이슈가 생길 수밖에 없다.
  • 그래서 지우고 재구성하는 게 추천된다. (물론 CNI를 설치하고 멀티 노드를 추가 구성해도 큰 문제는 없긴 할테지만, 더 깔끔한 게 좋다고 본다.)
$ minikube delete
$ minikube start --nodes {노드개수} --driver=docker
  • 커맨드는 위와 같다.

간단히 실습을 해본다.

  • selector 디렉토리를 준비한다.
  • minikube delete
    • 기존의 싱글노드 minikube 클러스터를 제거해준다.

  • minikube start --nodes 3 --driver=docker
    • 새롭게 멀티노드 minikube 클러스터를 생성해준다.

  • watch kubectl get node
    • watch 모드로 minikube 노드 3개를 확인해본다.

2. Pod 배치전략 중 NodeSelector에 대해 이해하고 실습한다.

  • scheduler가 Pod를 어떤 Node에 할당할 지 결정하는 기준이 되는 기본적인 평가 rule들을 이해해야 한다. 이를 Pod 배치전략이라 요약할 수 잇는데, 대표적인 전략은 다음과 같다.
    • Node Selector
    • Node Affinity
    • Pod Affinity
    • taint / toleration
  • 이번 편에서는 Node Selector에 대해 알아보고, 나머지는 다음 편에서 살펴볼 예정이다.

1) nodeName

  • nodeSelector에 대해 이해하기 전에 비교할만한 다른 방법에 대해 살펴볼 필요가 있다.
  • nodeName은 말그대로 node의 name 기반으로 Pod가 배치될 node를 결정한다.
  • nodeName을 이용하면 직관적이라는 강점은 있다.
  • 하지만 메니페스트(yml) 재활용성이 떨어지며, Node와 강결합되기 때문에 추천되지는 않는 방법이다.

2) nodeSelector

  • Node도 쿠버네티스 API 오브젝트로 관리되기 때문에 Labels을 가지고 있다.
  • Node에 설정된 Label을 기반으로 하여 Label Selector 기반 Pod 배치 가능하다.
  • Node Label 관리
    • 이미 띄워져있는 Node들에 대해선, kubectl을 통해 Node의 label 관리가 가능하다.
      1. {노드명}인 Node에 {key}={value} label 추가
      $ kubectl label node {노드명} {key}={value}
      1. {노드명}인 Node에 {key} label 제거
      $ kubectl label node {노드명} {key}-

    • Node를 새로 구성할 때 kubelet 옵션을 통해서 기본 Labels 설정도 가능하다고 한다.

간단한 실습을 들어가본다.

  • selector 디렉토리를 우선 만들고, 진입해서 파일을 준비한다.

node-name/deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-name
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      name: hello
      labels:
        app: hello
    spec:
      containers:
      - name: nginx
        image: nginxdemos/hello:plain-text
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
      nodeName: minikube
  • node-name 디렉토리를 구성하여 추가하였다.
  • app 이름은 hello, image는 nginx, nodeName은 minikube로 명세하였다.

node-selector/deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: node-selector
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:
    metadata:
      name: hello
      labels:
        app: hello
    spec:
      containers:
      - name: nginx
        image: nginxdemos/hello:plain-text
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
      nodeSelector:
        team: red
  • spec.containers와 동일한 뎁스에 nodeSelector라는 키를 추가하고, 그 아래 key-value 형식으로 명시한다. (즉, 어떤 Node에 배치될지가 정해진다. Node가 가지고 있는 label의 key와 value에 매칭되는 것이다.)

node-selector/set-node-labels.sh

kubectl label node minikube --overwrite team=green
kubectl label node minikube-m02 --overwrite team=red
kubectl label node minikube-m03 --overwrite team=red
  • 추가로 node-selector 디렉토리엔 여러 커맨드를 한번에 실행하기 위한 sh 스크립트도 준비해준다.
  • 내용을 보면, Node 마다 각기 다른 label을 추가하는 커맨드임을 알 수 있다.

node-name 활용 실습

  • node-name 디렉토리에서 실습을 진행한다.

  • kubectl apply -f deployment.yml
    • apply를 해준다.

  • watch kubectl get node
    • node가 3종류 임을 알 수 있다. (minikube, minikube-m02, minikube-m03)

  • watch kubectl get pod -o wide
    • watch 모드로 pod를 확인해보면 NODE가 모두 minikube인걸 알 수 있다. 즉 3개 노드 중 1개의 노드에 모든 Pod가 생성된 것이다.
    • node-name을 minikube로 설정했기 때문에 minikube node에만 Pod가 전부 스케쥴링이 된 것이다.

node-selector 활용 실습

  • node-selector 디렉토리에서 실습을 진행한다.
  • 참고로 권한 문제가 발생하면 다음 커맨드를 입력한다.
    • chmod +x set-node-labels.sh

  • 우선 watch 모드 실행을 위해 2개의 터미널을 새로 띄운다.
  • watch kubectl get pod
    • 실습 중에 1번 watch 터미널이라고 하겠다.
    • Pod의 상태를 실시간으로 볼 수 있다. 아직 아무것도 존재하지 않는다.
  • watch kubectl get nodes --label-columns team
    • 실습 중에 2번 watch 터미널이라고 하겠다.
    • Node의 상태를 실시간으로 볼 수 있다. 특정 label 컬럼도 볼 수 있도록 옵션을 주었다.
    • 현재 node가 3종류 임을 알 수 있다. (minikube, minikube-m02, minikube-m03)
    • 다만 아직 label의 team key에 할당된 value는 없다.

  • ./set-node-labels.sh
    • Node label 세팅부터 진행해준다. 2번 watch 터미널에 TEAM label이 추가되었다.

  • kubectl apply -f deployment.yml
    • 그다음 depoly를 apply 해준다. 1번 watch 터미널에 pod가 늘어났다.
    • node-selector 3개 추가되었는데, 노드명은 minkube-m02 혹은 minkube-m03이다.
    • deployment.yml에 명세해두었듯이, Team label이 red인 것만 select되서 Pod가 띄워지기 때문이다.
    • kubectl delete -f deployment.yml로 마무리 한다.
profile
그렇게 바쿠만도는 개발에 퐁당 빠지고 말았답니다.

0개의 댓글