K8s는 Pod를 어떤 노드에서 실행할지에 대한 다양한 옵션이 있고 아래 4가지 방식을 지원합니다.

  • Node Selector
  • Node Affinity & pod Affinity pod antiAffinity
  • node taint & pod toleration
  • cordon & drain

 

 

 

Node Selector?

  • Pod가 클러스터 안 어떤 노드에서 실행될지를 Label을 이용하여 지정하는 방식

 

 

Node Selector 테스트

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: nginx
    name: webserver
    ports:
    - containerPort: 80
  nodeSelector:
    cpu: "2core_over"

  • # kubectl label node w{1,2}-k8s cpu=2core_over
    • node 1, 2에 label 추가

  • cpu label이 지정된 노드에서만 pod가 실행됨을 확인 할 수 있다.

 

 

Node Affinity & antiAffinity?

  • Node Node Affinity
    • 특정 노드에서만 Pod가 실행되도록 하는 기능
    • Node Selector와 유사하지만 아래의 두가지 요구조건이 만족하는 Pod에만 스케줄링 하도록 지정 할 수 있습니다
      • requiredDuringSchedulingIgnoredDuringExecution
        • 스케줄링하는 동안 꼭 필요한 조건
      • preferedDuringSchedulingIgnoredDuringExecution
        • 스케줄링하는 동안 만족하면 좋은 조건
  • Pod Affinity
    • Pod들을 더 가깝게 배치하는 방법
  • Pod AntiAffinity
    • Pod들을 분산 배치하는 방법

 

 

Node Affinity 테스트

apiVersion: v1
kind: Pod
metadata:
  name: nginx-gpu-ssd
spec:
  containers:
  - name: webserver
    image: nginx:1.15
    ports:
    - containerPort: 8888
      protocol: TCP
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: disktype, operator: Exists}
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 10
        preference:
          matchExpressions:
          - {key: gpu, operator: In, values: ["true"]}
          - {key: disktype, operator: In, values: ["ssd"]}

  • w1-k8s 노드에 gpu=true cpu=2core disktype=ssd 레이블 추가

  • requiredDuringSchedulingIgnoredDuringExecution 설정에 의해서 disktype label이 존재하는 레이블 중에서 gpu가 true disktype이 ssd인 w1-k8s node가 스케줄링 되는것을 확인 할 수 있다
    • w1-k8s 가중치: 20
    • w2-k8s disktype 레이블이 없으므로 해당사항없음
    • w3-k8s 가중치: 10

 

 

Pod Affinity 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 5
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: backend
            topologyKey: kubernetes.io/hostname
      containers:
      - name: main
        image: busybox
        args:
        - sleep
        - "100000"

  • backend pod가 실행중인 w3-k8s node에서 frontend pod가 실행됨을 확인 할 수 있다

 

 

Pod AntiAffinity 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 5
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: backend
            topologyKey: kubernetes.io/hostname
      containers:
      - name: main
        image: busybox
        args:
        - sleep
        - "100000"
  • topologyKey
    • 노드 label을 이용해 pod의 affinity와 antiaffinity를 설정할 수 있는 또 하나의 기준
    • K8s는 Pod를 스케줄링 할 때 먼저 Pod의 label을 기준으로 대상 노드를 찾고, topology 필드를 확인하여 해당 노드가 원하는 노드인지 확인한다.

  • backend pod가 실행중인 w1-k8s node에서 frontend pod가 실행되지 않음을 확인 할 수 있다

 

 

 

node taint & pod toleration

  • node taint
    • 특정 Node에 taint를 설정하여 설정한 Node에는 Pod를 스케줄링 하지 않도록 할 수 있음.
      • master node인 m-k8s에는 taint NoSchedule가 설정돼 있어 해당 Node는 스케줄링을 받지 않도록 설정되어 있다
    • toleration
      • taint를 설정한 Node에 Pod를 스케줄링하려면 toleration을 설정해아 함
      • toleration이 있는 Pod는 동일한 taint가 있는 node를 포함하여 tain가 설정돼있지 않은 모든 node에 배치된다

 

 

node taint & pod toleration 테스트

1. taint 설정되지 않는 node에만 pod 배치여부확인

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx

  • # kubectl taint nodes w3-k8s key01=value01:NoSchedule
    • w3-k8s Node에 taint 설정
    • 형식: kebectl taint nodes 노드이름 키=값:효과
  • taint가 설정된 m-k8s ,w3-k8s Node에는 pod가 할당되지 않음을 확인 할 수 있다

 

2. Pod에 toleration 설정하여(taint가 동일한 Node는 없음) Node에 Pod 배치여부 확인

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx
      tolerations:
      - key: "role"
        operator: "Equal"
        value: "web"
        effect: "NoSchedule"

  • Taint가 설정돼있지 않은 w1-k8s, w2-k8s에만 pod가 스케줄링됨을 알 수 있다

 

3. Pod에 toleration 설정하여(taint가 동일한 Node는 있음) Node에 Pod 배치여부 확인

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx
      tolerations:
      - key: "role"
        operator: "Equal"
        value: "web"
        effect: "NoSchedule"

  • # kubectl taint node w1-k8s role=web:NoSchedule
    • w1-k8s Node에 taint 설정
  • taint와 tolerations이 일치하는 w1-k8s Node에 Pod가 스케줄링 됨을 확인 할 수 있다.
  • 또한 taint가 설정되지 않은 w2-k8s에 Pod에도 스케줄링 된다

 

4. Node에 전부 taint가 설정되어 있고 pod tolerations 설정이 맞지 않는다면?

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx
      tolerations:
      - key: "role"
        operator: "Equal"
        value: "web"
        effect: "NoSchedule"

  • 모든 Node에 taint가 설정되어 있고 Pod tolerations 설정이 맞지 않는 경우 pod는 pending 상태가 된다. 

 

 

 

cordon & drain?

  • 특정 Node에 있는 Pod들을 모두 다른 노드로 옮기거나 특정 Node에 Pod들을 스케줄링하지 않도록 제한하는 기능
  • cordon
    • 특정 노드에 Pod 스케줄링 금지
  • uncordon
    • 특정 노드에 Pod 스케줄링 해제
  • drain
    • 특정 노드에서 동작중인 모든 Pod를 제거
      • kubectl drain Node [option]
        • option
          • --ignore-deamonsets
            • DaemonSet이 관리하는 Pod들은 ignore
          • --force
            • RC, RS, Job, DaemonSet 또는 StatefulSet에서 관리하지 않는 Pod 제거

 

 

cordon & uncordon 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx

  • # kubectl cordon w1-k8s
    • w1-k8s Node를 cordon 설정
  • w1-k8s Node에 pod가 할당되지 않음을 확인 할 수 있다
  • # kubectl uncordon w1-k8s
    • cordon 해제

 

 

drain 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx

  • w3-k8s Node에서 Controller에 의해서 관리되지 않는 db pod와 deployment에 의해서 관리되는 webserver pod가 실행중이다.
  • # kubectl drain w3-k8s --ignore-daemonsets --force
    • Controller에 의해서 관리되지 않는 db pod는 삭제되고 deployment의 관리를 받는 webserver pod는 다른 Node에서 실행됨을 확인 할 수 있다.
  • w3-k8s Node는 cordon을 했을때와 동일하게 상태가 SchedulingDisabled인것을 확인 할 수 있다.
  • static Pod는 삭제되지 않습니다.

'클라우드 > K8s' 카테고리의 다른 글

K8s volume  (0) 2022.04.03
K8s 인증과 권한관리  (0) 2022.04.03
K8s Secret  (0) 2022.03.31
K8s Configmap  (0) 2022.03.31
K8s 버전 업그레이드  (0) 2022.03.18

+ Recent posts