6. [중급편] Qos, Node Scheduling, Service

데일리·2023년 11월 29일
post-thumbnail

1. Qos

Quality Of Service => 리소스 할당과 관련된 우선순위를 정하는데 사용된다.

Pod 종류에 따라 어떤 pod의 자원을 가져올건지가 결정이 된다. 각 pod의 종류는 따로 설정한다기 보다는 Request, Limit 설정에 따라 결정된다.

  • Guaranteed(보장): 해당 클래스의 파드는 자원에 대한 Request와 Limit가 설정이 되어 있고 CPU와 Memory의 설정 값들이 같아야한다. 다른 파드들이 자원을 사용하더라도 해당 pod은 자원을 보장받으며, 다른 파드에 의해 영향을 받지 않는다.
  • BestEffor(최선의 노력): 이 클래스의 파드는 리소스 Limit이나 Request가 없다. 이 클래스의 파드는 리소스에 대한 보장이 없으므로, 다른 파드들이 필요한 자원을 가져오기 위해 중단 될 수 있다!
  • Burstable(가변형): 이 클래스의 파드는 Request나 Limit자원이 설정이 둘 중 하나만 되어있거나 특정 컨테이너에서는 설정이 없는 경우이다. 이 경우 자원을 가변적으로 사용할 수 있지만 일정한 범위 내에서만 가능하다.

동작 방식은 이러하다, 만일 노드에 제한된 리소스가 있는데 pod1에 노드의 총합보다 많은 리소스를 사용해야할 때 먼저 BestEffor의 pod를 다운시키고 자원을 반환한 다음 pod1에 자원을 할당한다.
만약 이상태에서도 더 많은 리소스가 필요하다면 Burstable이 적용된 파드가 다운되면서 자원이 회수되고 Guaranteed pod가 마지막까지 안정적으로 유지 된다.

>> 그렇다면 Burstable pod이 여러개일 때 어떤 pod이 먼저 다운이 될까?

해당 문제를 해결하기 위해 Qos는 OOM score 기준을 따른다.

해당 사진을 처럼 App/Request의 메모리 비율 즉 사용률이 가장 많은 pod가 우선적으로 다운이 된다.

2. Node Scheduling

노드 선택

파드는 기본적으로 노드스케쥴링에 의해 노드에 할당된다. 그러나 운영자가 특정 노드를 사용하거나 사용하지 못하게 하도록 커스텀을 할 수 있는 기능이 있다.

  • NodeName: 노드의 이름을 직접 선택하여 할당하는 방법 => 실제에서는 노드명이 계속 변경되기 때문에 사용하지 않음
  • NodeSelector: 같은 key: value로 노드를 매칭(권장)
  • NodeAffinity: 파드에 키만 할당하는 경우인데 조건에 맞지 않는 파드여도 스케줄러가 자원이 많은 노드에 할당한다.

Pod간 집중/분산

여러 pod들을 한 노드에 집중시키거나 분산하여 할당할 수 있는 방법이 있다.

  • Pod Affinity: pod1에 pod Affinity 설정을 type:web으로 지정하면 해당 라벨로 지정한 파드들은 pod1과 같은 노드에 생성이 된다.
  • Anti-Affinity: 백업용 파드들을 위해 주로 사용이 되는데 pod1에 anti-affinity 속성을 지정하고 라벨을 설정하면 다른 Pod에 해당 라벨을 지정하면 다른 pod에 생성이 된다.

노드 제한

특정 노드에 아무런 pod할당을 제한하기 위해 설정

노드에 taint설정을 해놓으면 tolerant옵션이 없는 노드들은 할당이 안된다.

NodeAffinity

여러 조합으로 파드를 할당할 수 있는데 matchExpressions를 설정하여 특정 조건이 맞는 노드에 할당하도록할 수 있고 그 중에서 자원이 많은 노드에 할당이 된다.

required/preffered 속성이 있는데 required는 파드의 조건이 노드에 없으면 해당 노드에는 할당이 되지 않지만 preffered는 해당 조건이 있는 노드를 선호할 뿐 해당 키가 없더라도 적절하게 할당이 된다.

preffered weight: cpu 자원이 많은 노드에 할당이 대체적으로 될텐데 weight옵션을 넣으면 더 많은 키를 선호하게 된다.

PodAffinity

Pod Affinity ⇒ matchExpressions를 통해 조건에 맞는 노드가 아니라 파드에 매칭되는 조건을 찾는다

Pod Anti-AffinitymatchExpressions로 마스터 파드를 설정하면 해당 파드가 있는 노드에는 할당되지 않는다.

Topology key ⇒ 노드의 키를 판단하여 조건에 맞는 노드에 할당이 된다.

Taint, Tolerant


해당 pod의 tolerant옵션과 node의 taint의 조건이 모두 같아야한다. 만일 pod가 tolerant가 있더라도 다른 노드에는 할당이 가능하다

effect는 노드안에 있던 기존의 pod들에 대해 동작을 설정한다.

  • noSchedule: 이미 기존에 있던 pod들에 대해 삭제를 따로 진행하지 않는다.
  • PreferSchedule: toleration이 없는 파드들이 가급적 할당이 안되지 필수가 아니다. 자원이 없으면 할당이 될 수도 있음.
  • NoExcute: 기존에 있는 pod들 중에 tolerant가 없으면 삭제를 진행한다.

3. Service

쿠버네티스에서는 서비스가 만들어진 후에 서비스 ip로 접근을 하면 되지만 pod의 경우에는 자원들이 동시에 배포가 되거나 ip가 동적으로 할당이 되고 재생성되면 ip가 변경이 되기 때문에 ip주소로 접근이 쉽지가 않다.

이런 문제를 해결하기 위해 등장한게 DNS Service, headless 서비스이다.

pod가 외부의 특정 사이트에 접근을 해 데이터를 가져오는 경우, 접근 주소를 변경해야되는 상황일 때 exteranlName을 이용해 외부 연결을 pod의 재배포 없이 할 수 있다.


쿠버네티스 클러스터 내부에는 DNS 서버가 서비스 도메인 이름과 IP를 관리하며 Pod는 DNS를 통해 도메인 이름으로 서비스나 외부 리소스에 접근할 수 있다.

pod1이나 pod2를 선택하여 연결하고 싶을 때에는 pod의 headless 서비스를 연결하게 되면 DNS서버에 pod의 이름과 서비스의 이름이 붙어져서 도메인 이름으로 등록이 되어 pod에서 pod1으로 도메인 이름으로만 접근이 가능해진다.

External Name 서비스는 특정 외부 도메인 주소를 pod에 제공하면 도메인 이름만으로 외부소스에 접근이 가능하게 하는데 이 주소를 변경하고 싶은 경우 또는 해당 주소가 동적 ip라 변경되는 경우에 exteranlName을 사용하면 pod의 수정없이 서비스만 수정하여 외부 서비스를 연결 할 수 있다.

HeadLess Service


디폴트 네임스페이스에는 두개의 파드와 클러스터 ip로 설정된 서비스는 클러스터 DNS를 통해 연결이 된다. 클러스터 DNS 구조는 서비스의 이름, 네임스페이스, 서비스 도메인 이름, DNS 이름으로 구성되고 파드는 해당 ip의 네임 스페이스, pod 도메인 이름("pod"), DNS 이름이 결합되어 생성

만일 headless 서비스를 적용시에는 서비스의 이름 대신에 headless가 들어가고 pod의 dns에 pod의 이름과 headless이름으로 dns가 이루어진다.

Endpoint

업로드중..

쿠버네티스에서는 사용자가 서비스와 pod를 라벨과 셀렉터로 연결을 하지만 이는 내부에서 쿠버네티스가 엔드포인트 설정을 따로 해주는 것이다.

엔드포인트는 서비스의 이름과 동일한 이름으로 생성이되며 해당 엔드포인트에는 파드의 접속 정보가 포함된다. 이를 통해 사용자는 직접 라벨과 셀렉터를 사용하지 않고도 서비스와 파드를 연결할 수 있다.

Exteran Name 서비스를 활용하여 도메인이름을 지정하면 DNS 캐시가 내부와 외부 DNS 캐시가 외부 DNS를 찾아서 ip를 알아내어 사용한다, 이를 통해 서비스의 필요에 따라 pod의 수정없이 서비스만 수정하여 외부 서버에 접근할 수 있고 pod는 해당 서비스만 가르키기만 하면 된다.

해당 서비스는 MSA서비스를 사용할 때 주로 사용된다. 특정 서버에 ip를 통해 직접적으로 요청하기 보다는 externalName 서비스를 이용한다면 ingress를 거치지 않아도 되서 서비스의 자원 사용률도 줄어들게 되고 pod의 수정도 줄어들어 보다 효율적으로 관리할 수 있게 된다.

profile
하루에 한편 씩 읽기 좋은 테크 로그

0개의 댓글