-
Kubernetes (K8S): Scheduling공부합시다!/Kubernetes 2022. 12. 30. 00:15728x90
Scheduling 이란 Kubernetes에서 node의 상황에 따라 어떤 방식으로 Pod를 배치할 것인지를 결정하는 것입니다.
Scheduling 의미는
1). Kubernetes는 대부분 Multinode로 운영된다.
2). 여러개의 node를 하나의 인스턴스로 사용하는 효과를 준다.
3). 사용자의 입장에서는 하나의 인스턴스를 사용하지만 Kubernetes 여러대의 node를 관리함으로 pod를 어떤 node에 배치해야 할지를 결정해야 한다.
로 정의할 수 있습니다.
1. 스케줄링 순서
1.1. User가 K8S에게 Pod 생성 요청
1.2. K8S는 받은 모든 요청을 API Server가 제어, 따라서 사용자의 요청은 API Server로 전달됨.
1.3. API Server는 etcd에 정보를 저장 후 User에게 결과를 전달
1.3.1. etcd: K8S 모든 요소의 정보 저장소
1.4. API Server는 스케줄러에게 해당 파드를 생성하라는 정보 전달, 스케줄러는 Pod에 대한 정보를 식별
1.4.1. 스케줄러: Pod를 Node에 배치하는 권한을 갖고 있음.
1.5. 스케줄러는 Node 중 Pod를 배치하기에 적합한 Node를 내부적인 Rules에 따라 결정 후 API Server에게 통보
1.6. API Server는 스케줄러에게서 전달받은 Node에 Kubelet를 통하여 Pod를 생성하는 명령 실행
1.7. Kubelet는 Pod를 생성하는 명령을 실행시킴으로서 Pod에 Container를 배치.
2. Pod 배치 결정과 Filtering
2.1. Pod 배치 결정 3단계
2.1.1. Node Filtering
2.1.2. Node Scoring(노드 우선순위 계산)
2.1.3. 실제 예약 작업
2.2. Filtering 방식
2.2.1. Port Filter
2.2.2. Hostname Filter
2.2.3. NodeSelector Filter
2.2.4. Volume Filter
2.2.5. Resource Filter
3. 인위적 스케줄링 방식
3.1. NodeName
3.1.1. Pod Spec에 NodeName를 기술
3.1.2. 간단하면서 우선 순위가 가장 높은 방법
3.1.3. 구성파일 작성
vi centnode.yml apiVersion: v1 kind: Pod metadata: name: no1-os spec: containers: - name: centno1 image: centos:7 command: ["/bin/bash","-c","while true; do sleep 1000; done"] imagePullPolicy: IfNotPresent nodeName: node1 --- apiVersion: v1 kind: Pod metadata: name: no2-os spec: containers: - name: centno2 image: centos:7 command: ["/bin/bash","-c","while true; do sleep 1000; done"] imagePullPolicy: IfNotPresent nodeName: node2
3.1.4. 확인
# kubectl get pod -o wide # kubectl apply -f centnode.yml # kubectl get pod -o wide # kubectl delete -f centnode.yml # kubectl get pod -o wide
3.2. NodeSelector
3.2.1. Node에 설정되어 있는는 Label을 이용하여 Pod를 배치
3.2.2. 단 Node에 반드시 Label에 설정되어 있어야 함.
3.2.3. 구성파일 작성
vi centnodesec.yml apiVersion: v1 kind: Pod metadata: name: no1-os spec: containers: - name: centno1 image: centos:7 command: ["/bin/bash","-c","while true; do sleep 1000; done"] imagePullPolicy: IfNotPresent nodeSelector: env: test --- apiVersion: v1 kind: Pod metadata: name: no2-os spec: containers: - name: centno2 image: centos:7 command: ["/bin/bash","-c","while true; do sleep 1000; done"] imagePullPolicy: IfNotPresent nodeSelector: env: prod
3.2.4. node에 label 구성
# kubectl get nodes --show-labels 기존 node의 label 확인 # kubectl label nodes node1 env=test # kubectl label nodes node2 env=prod node1에 env=test, node2에 env=prod 라는 라벨 부여 # kubectl get nodes --show-labels
3.2.5. 적용 및 확인 그리고 삭제
# kubectl apply -f centnodesec.yml # kubectl get pod -o wide # kubectl delete -f centnodesec.yml # kubectl labels nodes node1 env- # kubectl lables nodes node2 env- # kubectl get nodes --show-labels
- 위의 두 방식은 그러나 치명적인 문제점을 내포하고 있습니다.
- node의 이름이나 label이 일치하지 않으면 pod가 생성이 되지 않는다는 점입니다.
- taint는 지정된 node에는 일반적인 pod를 배포할 수 없도록 할때 유용합니다.(개발이나 스테이징 환경 분리시)
3.3. Taint & Toleration
3.4. Node Affinity
3.5. Pod간 Affinity & Anti Affinity
- cordon 이나 drain은 node를 스케줄링 작업에서 제외 시키는 방식입니다.
- drain의 경우 node의 하드웨어적인 유지보수 시 사용이 가능하며 모든 pod가 삭제됩니다.
3.6. cordon & nocordon
3.6.1. node에 실행되고 있는 pod에는 영향을 미치지 않는다.
3.6.2. cordon이 설정된 node에는 더 이상 pod가 배포되지 않는다.
# kubectl get nodes # kubectl get pod -o wide # kubectl create deployment test-cor --image=nginx:1.14 --replicas=3 node에 3개의 pod를 배포하는 deployment test-cor 생성 # kubectl get pod -o wide pod가 배포된 node 확인 # kubectl cordon node2 node2에 condon(더 이상 스케줄링 하지 않음을 명시적으로 선언) 설정 # kubectl get nodes node2을 확인하면 더 이상 스케줄링 하지 않음을 확인 # kubectl get pod -o wide node2의 기존 pod는 정상적으로 실행 중
# kubectl scale deployment test-cor --replicas=5 node에 pod를 2개를 더 배포하기 위해 복제 pod의 수를 5개로 늘림 # kubectl get pod -o wide pod 확인 -> node2에는 배포가 되지 않는 것을 확인 # kubectl uncordon node2 node2를 uncondon(다시 스케줄링 하겠다는 명시적인 선언)으로 구성 # kubectl get nodes 현재 node 상태 확인, 다시 schedulingDisable 사라짐. # kubectl scale deployment test-cor --replicas=7 node에 pod를 7개로 배치 # kubectl get pod -o wide 다시 node2에 pod가 배포된 것을 확인
3.7. drain
3.7.1. node에 존재하는 모든 pod가 삭제된다.
3.7.2. 사용가능한 다른 node에서 새로운 pod가 배포되어 replicas에서 지정한 pod갯수를 준수한다.
3.7.3. node의 Hardware적 유지보수로 인하여 더 이상 운영할 수 없을때 주로 사용합니다.
# kubectl get nodes 모든 node 준비상태 확인 # kubectl get pod -o wide pod의 자세한 정보 출력 # kubectl create deployment test-drain --image=nginx:1.14 --replicas=3 nginx 1.14버젼 image를 이용하여 pod 3개를 배포 daemon-set(모든 node에 pod 균등 배포)의해 각 node에 동일하게 1개 pod 배포 확인 # kubectl drain node2 node2을 drain 시킴 그러나 daemont-set에 의해서 error 발생 메세지를 확인해보면 --ignore-daemonsets 사용하라고 명시되어 있음.
# kubectl drain node2 --ignore-daemonsets ignore 옵션에 의해서 node2에 drain 적용 # kubectl get pod -o wide node2의 pod가 제거되고 replicas 지정된 pod 갯수를 맞추기 위해 node3에 새로운 pod 배포확인 # kubectl get nodes node2를 확인해보니 SchedulingDisabled로 변화 확인 # kubectl uncordon node2 node2를 다시 스케줄링 가능하게 끔 uncordon 실행 # kubectl get nodes node2를 확인해보니 SchedulingDisabled 사라지고 다시 스케줄링 가능하게 됨.
# kubectl scale deployment test-drain --replicas=6 pod의 갯수를 6개로 확장 # kubectl get pod -o wide 3개의 pod가 추가되면서 daemon-set에 의해 node2에 2개, node1에 1개가 추가됨 세개의 node에서 각 2개의 pod 실행됨을 확인
affinity는 추후에 내용을 추가하겠습니다.
지금은 이 정도만 하셔도 훌륭합니다.
Have a nice day!
728x90'공부합시다! > Kubernetes' 카테고리의 다른 글
Kubernetes(K8S): Multi Container POD (0) 2023.01.02 Kubernetes (K8S): Object - 2. POD (0) 2022.12.30 Kubernetes(K8S): yaml 파일 분석 (0) 2022.12.29 Kubernetes (K8S): Network - 2. POD Networking (0) 2022.12.29 Kubernetes (K8S): App이 실행되지 않는 image(Centos, Ubuntu등) 실행 (0) 2022.12.28