본문 바로가기
DevOps/Kubernates

[CKA] 62-75 Node Affinity, Taints and Tolerations, DaemonSets, Static Pod

by BenKangKang 2023. 4. 3.

62-75

63. Solution - Node Affinity

  • 주요 목적
    • Pod가 특정 노드에서 호스팅되도록 하는 것
apiVersion: v1
kind: Pod
metadata:
 name: myapp-pod
spec:
 containers:
 - name: data-processor
   image: data-processor
 affinity:
   nodeAffinity:
     requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: size
            operator: In
            values: 
            - Large
            - Medium
key 필드 값 설명
In values[] 필드에 설정한 값 중 레이블에 있는 값과 일치하는 것이 하나라도 있는지 확인합니다.
NotIn In과 반대로 values[]에 있는 값 모두와 맞지 않는 지 확인합니다.
Exists key 필드에 설정한 값이 레이블에 있는지만 확인합니다. (values[] 필드가 필요 없습니다.)
DoseNotExist Exists와 반대로 노드의 레이블에 key 필드 값이 없는지만 확인합니다.
Gt Greater than의 약자로 values[] 필드에 설정된 값이 설정된 값 보다 더 큰 숫자형 데이터 인지 확인합니다. 이 때 values[] 필드에는 값이 하나만 있어야 합니다.
Lt Lower than의 약자로 values[] 필드에 설정된 값이 설정된 값 보다 더 작은 숫자형 데이터 인지 확인합니다. 이 때 values[] 필드에는 값이 하나만 있어야 합니다.

Node Affinity Types

  • Available
    • requiredDuringSchedulingIgnoredDuringExecution (강한 규칙)
      • 스케쥴링하는 동안 꼭 필요한' 조건
    • preferredDuringSchedulingIgnoredDuringExecution (약한 규칙)
      • 스케쥴링하는 동안 만족하면 좋은' 조건입니다. 꼭 이 조건을 만족해야하는 것은 아니라는 의미입니다.
  • Planned
    • requiredDuringSchedulingRequiredDuringExecution
    • preferredDuringSchedulingRequiredDuringExecution

스케줄링 vs 실행 중

  • 스케줄링
    • 팟이 존재하지 않는, 처음 생성되는 상태
  • 실행
    • 팟이 실행되고 있는 상태

Preferred vs Required vs Ignored

  • Preferred
    • 권장
    • 조건에 맞는 노드를 찾지 못하는 경우 선호도 규칙을 무시.
  • Required
    • 강제
    • 조건에 맞는 노드를 찾지 못하는 경우 팟 자체가 예약되지 않음.
  • Ignored: 조건 무시.
    • requiredDuringSchedulingIgnoredDuringExecution
      • 스케줄링에서는 필수, 실행 중에는 조건 무시 → 일단 예약되면 영향을 미치지 않음
  • 참고 https://minkukjo.github.io/study/docs/kubernetes/node-isolation/

63. Practice Test - Node Affinity

Link to Practice Test: https://uklabs.kodekloud.com/topic/practice-test-node-affinity-3/


64. Solution - Node Affinity (Optional)


65. Taints and Tolerations vs Node Affinity

  • Taint: 오염, 감염
    • 노드에 설정하는 것.
    • 노드가 파드 셋을 제외시킬 수 있다.
  • Toleration: 관용, 묵허
    • 파드에 적용하는 것

예시

https://velog.velcdn.com/images/2214yj/post/1c4b1c7d-b3f1-4586-af96-4fd4227e31e6/image.png

  • 요구사항
    • 위에는 같은 색의 노드만 배치되면 좋겠다.
  • 동작
    • 파드가 생성되면 노드는 톨로레이션 설정이 된 팟만 스케줄링한다.

주의

  • taint, toleration 설정만은 정확히 노드에 배포되는 것을 보장하는 것이 아니다. 허용 비허용만 결정할 뿐

taint, toleration, Node Affinity 이용해서 노드 전용으로 만들기

1. Node Affinity

https://velog.velcdn.com/images/2214yj/post/ad8d0de5-7994-4317-9b5f-4fa667d1718d/image.png

  • label 에 해당하는 노드에 색깔 팟들이 잘 배치된다.
  • 한계: 아직까지 기타 색상 팟이 색상 노드에 배치될 가능성이 있다.

2. Node Affinity + taint, toleration

https://velog.velcdn.com/images/2214yj/post/8c778975-76cc-4ff0-b814-9b0beeb9b499/image.png

  • Taint + Toleration: 색이 다른 파드가 노드에 놓이는 것을 막는다.
  • Node Affinity: 파드가 각 색상 노드에 배치되도록 한다.

66. Resource Requirements and Limits

  • 3개의 노드로 이루어진 쿠버네티스 클러스터
    • 각 노드에 CPU, 메모리, 디스크가 사용 가능한 리소스만큼 할당.
    • 파드가 노드에 놓일 때마다 그 노드에 사용 가능한 리소스를 소비한다.
  • 쿠버네티스 스케줄러
    • 파드가 어느 노드로 갈지 결정할 때 파드가 요구하는 리소스의 양과 노드에서 사용 가능한 리소스의 양을 고려한다.

리소스가 없다면?

https://velog.velcdn.com/images/2214yj/post/69340777-ad3a-46b5-b8e6-1ad14a30f432/image.png

  • 노드에 충분한 리소스가 없으면 스케줄러는 노드에 파드를 놓는 것을 피한다.
  • 만약 사용 가능한 노드가 없으면 파드 배포를 보류한다.

Resource Requirements (리소스 필요 사양 명시)

  • 기본적으로 K8은 포드 또는 포드 내의 컨테이너에 0.5CPU와 256Mi메모리가 필요하다고 가정합니다. Resource Request이것은 for a container 로 알려져 있습니다 .
apiVersion: v1
kind: Pod
metadata:
  name: simple-webapp-color
  labels:
    name: simple-webapp-color
spec:
 containers:
 - name: simple-webapp-color
   image: simple-webapp-color
   ports:
    - containerPort:  8080
   resources:
     requests:
      memory: "1Gi"
      cpu: "1"
  • 파드를 정의할 때 resources 영역을 추가하고 필요한 리소스에 대해 요청할 수 있다.
  • 포드 내의 애플리케이션에 기본 리소스보다 더 많은 리소스가 필요한 경우 포드 정의 파일에서 설정해야 합니다.

https://velog.velcdn.com/images/2214yj/post/5281551b-b721-4f6a-b5ef-a12bd07c79d3/image.png

  • CPU
    • 0.1CPU → 100m (밀리) 표현함

https://velog.velcdn.com/images/2214yj/post/d83f0aa7-6aa8-4fae-b2f2-5515e38d3e56/image.png

  • Memory
    • Gibibyte → 1024 단위

Resources - Limits (리소스 제한 사양 명시)

https://velog.velcdn.com/images/2214yj/post/6279b519-faa7-4cc4-9bb3-8b625b8e359c/image.png

  • 도커 세계에서 도커 컨테이너는 노드에서 소비할 수 있는 리소스에 한계가 없다. → 하나의 컨테이너에서 다른 컨테이너에 영향을 줄만큼 리소스를 소비할 수 있다.
  • 하지만 파드의 리소스 사용량에는 제한을 둘 수 있다.
    • 만약 특별히 파드의 리소스 사용량을 제한하지 않으면 하나의 파드는 1 vCPU, 512 Mi의 기본 한도를 갖게 된다.
apiVersion: v1
kind: Pod
metadata:
  name: simple-webapp-color
  labels:
    name: simple-webapp-color
spec:
 containers:
 - name: simple-webapp-color
   image: simple-webapp-color
   ports:
    - containerPort:  8080
   resources:
     requests:
      memory: "1Gi"
      cpu: "1"
     limits:
       memory: "2Gi"
       cpu: "2"
  • 만약 기본 한도를 바꾸고 싶다면 파드 정의 파일의 resources 영역에 한도(limits)를 지정하면 된다.
  • 파드가 지정된 한도를 초과하여 자원을 소비하게 되면 어떻게 될까
    • CPU
      • 쿠버네티스가 CPU를 조절하여 지정 한도를 넘지 않도록 한다. 따라서, 컨테이너는한도를 초과하는 CPU 리소스를 사용할 수 없다.
      • 쓰로틀
    • 메모리
      • 자신의 한도보다 더 많은 메모리를 소모하려고 하면 그 파드는 즉시 종료된다.

67. Note on default resource requirements and limits

  • 네임스페이스를 생성해서 다른 리소스들로부터 분리한 다음 LimitRange를 정의하는 manifest file을 작성해서 default limits과 default requests를 정의할 수 있다.
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256Mi
    type: Container

https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-limit-range
spec:
  limits:
  - default:
      cpu: 1
    defaultRequest:
      cpu: 0.5
    type: Container

https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/cpu-default-namespace/

References:

https://kubernetes.io/docs/tasks/configure-pod-container/assign-memory-resource

메모리의 default limits과 default requests를 정의하는 LimitRange manifest file

https://velog.velcdn.com/images/2214yj/post/99a55abc-d60c-492c-9178-8c8536ae0c13/image.png

CPU의 default limits과 default requests를 정의하는 LimitRange manifest file

https://velog.velcdn.com/images/2214yj/post/28b734e3-9b1d-4b84-9dcf-be21a7b96b6a/image.png


68. A quick note on editing PODs and Deployments

아래 이외의 사항들은 edit pod가 불가능하다.

  • spec.containers[*].image
  • spec.initContainers[*].image
  • spec.activeDeadlineSeconds
  • spec.tolerations
  • 이것들은

금지 팟도 가능하게 하는 방법

1. kubectl edit pod 할려던 팟 명세를 복사하고 기존 팟 삭제

  • kubectl edit 명령어를 실행해서 편집창을 열고 수정한 다음, 파일의 모든 내용을 복사해서 임시 파일에 붙여 넣고 기존의 pod를 삭제하고 임시 파일의 내용을 파드를 재생성하면 된다.
  • 또는 kubectl get pod webapp -o yaml > my-new-pod.yaml 명령어로 파드 정의 파일을 추출하고 변경사항을 수정한 다음, 기존의 파드를 삭제하고 새로운 파드 정의 파일로 파드를 재생성하면 된다.
  • 파드와 달리, Deployments는 정의 파일의 파드 템플릿 영역에서 아무 필드나 수정 가능하다.따라서, kubectl edit deployment my-deployment 명령어를 사용하면 된다.해당 명령어를 실행하면 자동으로 기존의 파드가 삭제되고 새로운 파드가 재생성된다.

69. Practice Test - Resource Requirements and Limits


70. Solution: Resource Limits


71. DaemonSets

https://velog.velcdn.com/images/2214yj/post/5b7c96bd-e461-4a3a-977a-9b45d313e38f/image.png

  • 데몬셋은 ReplicaSet 같은 것이다.여러 개의 인스턴스 파드를 배포하도록 도와준다.
  • ReplicaSet과 달리, 클러스터의 노드마다 최대 1개의 파드를 실행한다.
    • 클러스터에 새 노드가 추가될 때마다 파드 복제본이 자동으로 해당 노드에 추가된다.
    • 노드가 제거되면 파드는 자동으로 제거된다.
    • 즉, 데몬셋은 파드의 복사본을 클러스터 내 모든 노드에 항상 존재하게 한다

DaemonSets - UseCases

https://velog.velcdn.com/images/2214yj/post/d34f4b92-9684-42a5-8f51-c9c1147caa43/image.png

Untitled

  • Monoitoring Solution이나 Logs Viewer를 파드의 형태로 배포하기에 최적이다.
    • 클러스터 내 모든 노드에 필요한 kube-proxy와 wave-net과 같은 네트워킹 솔루션은 데몬셋의 좋은 예시이다.
  • 데몬셋이 알아서 동작하기 때문에 클러스터에 변화가 있을 때 노드에서 해당 파드를 추가하거나 제거할 필요가 없다.
  • 셋 정의 파일을 통해 데몬셋을 생성할 수 있다.

DaemonSets - Definition

apiVersion: apps/v1
kind: Replicaset
metadata:
  name: monitoring-daemon
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: monitoring-agent
  template:
    metadata:
     labels:
       app: monitoring-agent
    spec:
      containers:
      - name: monitoring-agent
        image: monitoring-agent
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: monitoring-daemon
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: monitoring-agent
  template:
    metadata:
     labels:
       app: monitoring-agent
    spec:
      containers:
      - name: monitoring-agent
        image: monitoring-agent
  • 데몬셋 정의 파일은 레플리카셋 정의 파일과 몹시 흡사하다. 거의 kind만 다름.
  • $ kubectl create -f daemon-set-definition.yaml

View DaemonSets

https://velog.velcdn.com/images/2214yj/post/235aa81f-fda9-48a7-a939-3c5372e3d9a6/image.png

  • To list daemonsets

    $ kubectl get daemonsets

  • For more details of the daemonsets

    $ kubectl describe daemonsets monitoring-daemon

How DaemonSets Works

  • 쿠버네티스 버전 1.2 이전
    • 각 팟에 nodeName을 지정하는 방식으로 데몬셋이 동작했다.
  • 쿠버네티스 버전 1.2 이후
    • 각 팟에 nodeAffinitydefault scheduler 를 사용하여 데몬셋을 각 노드에 스케줄링한다.

72. Practice Test - DaemonSets

Practice Test: https://uklabs.kodekloud.com/topic/practice-test-daemonsets-2/


73. Solution - DaemonSets


74. Static Pods

https://velog.velcdn.com/images/2214yj/post/f1501cd2-043a-47af-835d-6861732d6f5e/image.png

  • 강의 초반에 이야기했듯이 kubelet은 kubeAPI 서버에 의존해 노드에 파드를 배포한다.
    • kubelet이 할 줄 아는 건 컨테이너 엔진에 팟을 생성을 요청하는 것
  • kube-scheduler의 결정에 기초해 노드에 로드할 팟을 결정하고, 이는 ETCD 클러스터에 저장된 상태에 기반하여 걸정된다.

Static Pods

https://velog.velcdn.com/images/2214yj/post/0d53e87a-d32a-451d-8746-30412a3ef552/image.png

  • 팟 디렉토리 설정된 예시

Untitled

  • API 서버 개입 없이 kubelet이 자체적으로 생성하는 포드
  • 팟만 만들 수 있음. 레플리카 셋, 디플로이먼트는 생성 불가능. → 팟 수준에서만 작동한다
  • 방법
    • 노드에 포드 정의 파일을 로컬에 배치한다. 그리고 주기적으로 파일을 확인하고 팟을 생성한다.
    • 정의 파일을 삭제하면 자동으로 삭제한다.

설정 방법

1. Static Pod를 만들기 위한 지정된 디렉터리 설정

  • kubelet.service의 옵션으로 전달된다.
    • kubelet.service execStart 할 떄 —pod-manifest-path
    • —pod-manifest-path 보면 etc/쿠버네티스 매니페스트 폴더에 설정된 것을 볼 수 있다.

https://velog.velcdn.com/images/2214yj/post/411e7dfe-efdc-4d31-8545-eab05ea4f7ae/image.png

2. kubelet.service의 옵션으로 직접 디렉터리 위치를 지정하는 대신 디렉터리 위치를 저장한 구성 파일을 만들고 구성 파일을 전달하는 것

  • kubeadm 툴은 후자의 방법을 사용한다.
  • kubelet.service execStart 할 떄 kubeconfig

https://velog.velcdn.com/images/2214yj/post/7c4d2d57-3fa6-48e6-8bd4-00d7a81003a9/image.png

커맨드 유틸리티는 kube API 서버와 작동한다.

https://velog.velcdn.com/images/2214yj/post/d0412c08-8bef-43b3-ad58-858892dab8d2/image.png

The kubelet can create both kinds of pods

Untitled

API 서버 방식, 정적 방식 동시에 가능하다

  • kubelet은 두 종류의 포드(정적 포드와 API 서버의 포드)를 동시에 생성할 수 있습니다.
  • kubelet은 Static Pod 정의 파일로부터 파드를 생성할 수 있으며 kube-api server로부터 입력값 을 제공받아 파드를 생성할 수 있다.

kube-api server가 정적 팟을 인식하나?

  • kube-api server는 kubelet이 만든 static pod를 인식한다. → kubectl 명령어를 통해 파드를 조회하면 다른 파드들과 동일하게 static pod가 조회된다.
  • 가능한 이유
    • kubelet이 static pod를 만들 때 쿠버네티스 클러스터에 포함되어 있다면 kube-api server에 미러 개체 를 만들도록 요청
  • kube-api sever에서 보이는 미러 개체는 읽기 전용
    • 파드에 대한 세부사항은 볼 수 있지만 다른 파드처럼 편집하거나 삭제할 수 없다.

Static Pods - Use Case

https://velog.velcdn.com/images/2214yj/post/8b862192-990e-4250-b8c4-e689be3b8797/image.png

  • Static Pod는 쿠버네티스 control plane에 의존하지 않기 때문에 Static Pod를 이용해서 control plane에 구성요소를 배포할 수 있다.
  • 이렇게 하면 서비스를 구성하는 바이너리를 다운로드하거나 서비스 충돌을 걱정할 필요가 없다. 만약 어떤 서비스가 고장나면 kubelet이 자동적으로 재가동해준다.
    • 이 방법이 kubeadm 툴이 쿠버네티스 클러스터를 설정하는 방법이다.
  • 그래서 kube-system 네임스페이스에 파드를 조회할 때 control plane의 구성요소를 확인할 수 있는 것이다.

데몬셋 vs 정적팟

https://velog.velcdn.com/images/2214yj/post/880aaabe-15c5-4980-a142-bc8a721af022/image.png

  • 데몬셋은 응용 프로그램의 인스턴스 하나가 클러스터 내 모든 노드에서 사용 가능하도록 하는 데 사용된다. 데몬셋은 kube-api server를 통해 설정된다.
  • 반면에 Static Pod는 kube-api server나 control plane의 방해 없이 kubelet이 직접 생성한다. 또한 Static Pod은 control plane의 구성요소 자체를 배포하는데 사용될 수 있다.
  • kube-scheduler는 데몬셋과 Static Pod 에게 둘 다 무시된다.

75.

Practice Test - Static Pods

Practice Test Link: https://uklabs.kodekloud.com/topic/practice-test-static-pods-2/

I hear and I forget. I see and I remember. I do and I understand.

댓글