본문 바로가기
쿠버네티스

파드 & 서비스 정리

by 녤 2023. 2. 17.

 

1. 파드

 

컨테이너: 파드 안에는 하나의 독립적인 서비스를 운영할 수 있는 컨테이너가 존재한다. 컨테이너들은 서비스를 연결할 수 있도록 포트 번호를 가지고 있다. 한 컨테이너가 포트를 한 개 이상 가질 수 있지만, 한 파드 내에서 컨테이너들 끼리는 포트 번호가 중복될 수 없다. 한 파드 내의 컨테이너들은 하나의 호스트로 묶여 이ㅛ으며 파드 내에서 다른 컨테이너로 접근할 시에는 포트 번호를 통해서 접근이 가능하다. 파드 생성 시에는 IP 주소가 할당되고, 쿠버네티스 클러스터 내에서만 IP를 통해서 파드에 접근이 가능하며 외부에서는 접근이 불가능하다. 파드에 문제가 생길 경우에는 시스템에 파드를 삭제하고, 다시 재생성한다. 이 때 파드가 삭제되기 전에 사용하던 IP주소는 삭제되고 새 IP 주소를 할당 받게 된다. 

 

 

라벨: 목적에 따라 오브젝트를 분류하고, 분류된 오브젝트들만 따로 골라서 연결하기 위한 것으로 파드 뿐만이 아니라 모든 오브젝트에 라벨을 달 수 있다. 라벨의 사용률은 파드가 제일 많다. 라벨은 Key와 Value로 이루어져 있다. 한 파드 내에 여러개의 라벨이 다는 것이 가능하며 라벨을 통해서 자신이 원하는 파드에만 접속하는 것 역시 가능하다. 사용목적에 따라 라벨을 잘 달아 놓으면 해시태그처럼 사용하는 것이 가능하다. 

 

노드 스케줄: 파드는 여러 노드들 중 하나의 노드에 올라가야 한다. 이때, 파드가 올라갈 노드는 수동으로 직접 설정하는 것도 가능하고, 쿠버네티스가 자동으로 지정해주기도 한다. 

 

① 직접 선택

노드에 라벨을 달고, 파드를 생성할 때 노드를 지정하여 파드가 어떤 노드에 올라갈 지를 직접 선택할 수 있다. 파드 생성시 nodeSelector 항목에 노드의 라벨과 매칭되는 Key Value를 넣으면 된다. 

 

② 쿠버네티스가 자동으로 선택

 

노드에는 사용 가능한 자원량이 존재한다. 대표적으로 메모리와 CPU가 있는데, 만약 파드가 올라갈 노드를 직접 선택하지 않는다면 파드에서 요구하는 메모리 양과 노드에 남아 있는 메모리 양을 확인하여 쿠버네티스가 해당 파드가 올라갈 노드를 지정하게 된다. (파드를 설정할 때 사용량을 넣는 이유는) 만약 사용량을 설정하지 않으면 파드 내의 앱에서 부하가 생길 경우, 노드에 있는 자원을 무한정으로 사용하려 할 것이고, 그렇게 되면 노드 내의 다른 파드들도 죽게 되기 때문에 사용량을 지정하게 된다. 

 

각 자원에 대한 특성 때문에 메모리와 CPU가 다르게 작동하고, 메모리의 경우에는 초과되면 종료한다. 

 

 


 

2. 서비스 

 

 

① 클러스터 IP(Cluster IP)

 

서비스는 기본적으로 클러스터 IP를 가지고 있다. 서비스를 파드에 연결하면 서비스 IP를 통해서도 파드에 접근하는 것이 가능하다. 파드 내에도 클러스터에서 접근할 수 있게 하는 IP가 존재하지만 서비스를 통해서 파드에 접근하는 이유는 다음과 같다. 파드는 쿠버네티스에서 장애 등으로 언제든지 죽을 수 있고, 죽으면 다시 재생성 되도록 설정 되어 있는 오브젝트이다. 이때, 파드의 IP는 파드가 재생성될 때 변경되기 때문에 파드 IP는 신뢰성이 떨어진다. 하지만 서비스 IP는 사용자가 직접 지우지 않는 이상 삭제되거나 재생성되지 않는다. 따라서 비스 IP로 접근할 시 항상 연결되어 있는 파드에 연결이 가능하다. 서비스의 종류는 다앙하고, 그 종류에 따라 파드에 접근하도록 도와주는 방식에 차이가 존재한다. 그 중 가장 기본적인 방식이 클러스터 IP이다. 

 

쿠버네티스 클러스터 내에서만 접근이 가능한 IP으로 쿠버네티스의 대시보드 관리 및 서비스 상태를 디버깅하는 역할이다. 클러스터 내의 다른 모든 오브젝트들은 접근 가능하지만 외부에서는 접근이 불가하다해당 아이피를 통해 여러 파드들과 연결이 가능하고, 여러 파드가 연결될 경우 서비스가 트래픽을 분산시켜 파드에 전달해주는 역할을 한다. 클러스터 IP를 사용할 때는 type을 통해서 지정이 가능하다 그렇지만 기본값이 클러스터 IP이기에 굳이 지정할 필요는 없다. 

 

 

② NodePort

 

노드 포트를 사용하면 쿠버네티스 클러스터에 연결된 모든 노드에게 똑같은 포트가 할당 된다. 또한 외부에서 어떤 노드든 해당 IP의 포트로 접근할 시에는 해당 서비스에 연결된다. 이때, 서비스는 연결된 파드에 트래픽을 전달하게 된다. 또한 노드 포트는 파드가 있는 포트에만 할당되는 것이 아닌 모든 노드에 포트가 만들어진다. 대부분의 호스트 IP는 보안적으로 내부망에서만 접근 가능하게 네트워크를 구성하므로 노드 포트는 클러스터 밖에서 내부 망 안으로 접근해야 할 때 사용된다. 

 

만약 각 노드에 파드가 하나씩 올라가 있는 상태에서 1번 노드의 IP로 접근하더라도 서비스는 노드 2에 있는 파드에 트래픽을 전달할 수도 있다. 이는 비스 입장에서는 어떤 노드에게서 온 트래픽인지 상관 없이, 자신과 연결된 파드에게만 트래픽을 전달해주면 되기 때문이다. 특정 노드포트의 IP로 접근하는 트래픽을 서비스가 해당 노드 위에 있는 파드에만 전달하게 하기 위해서는 externalTrafficPolicy:Local을 사용하면 된다. 노드 포트 타입으로 만들어도 서비스에는 기본적으로 클러스터 IP가 할당 되어 클러스터 IP와 같은 기능이 포함되게 된다. 

 

 

③ Load Balacner

 

각자의 노드에 트래픽을 분산 시켜주는 역할을 하며 그 외의 다른 부분은 노드 포트와 거의 유사하다. 따라서 Load Balancer는 실제적으로 외부에 서비스를 노출 시킬 때 사용한다. 내부 IP가 노출되지 않고 외부 IP를 통해서 안정적으로 서비스를 노출하는 것이 가능하다는 장점이 있다. Load Balancer에 접근하기 위한 외부 접속 IP주소는 쿠버네티스를 설치할 때 기본적으로 생성되는 것이 아니기에 별도로 외부접속 IP를 할당하는 플러그인이 필요하다. 

 

 

 


 

파드의 라이프 사이클 

 

파드에도 라이프 사이클이 존재하고, 어떤 파드든 생성되고 사라지기까지 Pending → Running → Succeeded → Failed 의 단계를 가지게 되고 각 단계마다 행해지는 행동이 다르다. 

 

파드의 status  안에는 phase는 파드의 전체 상태를 대표하는 속성이 있고, Pending, Running, Succeeded, Failed, Unknown과 같은 상태값들이 존재한다. 또한 파드가 생성되면서 실행하는 각 단계과 상태를 알려주는 속성인 condition과 Condition에 대한 세부 사항을 알려주는 항목인 Reason이 있다. condition에는 각각 Initialized, ContrainerReady, PodScheduled, Ready와 같은 값들이 있다. Reason에는 ContainersNotReady 와 PodCompleted와 같이 각각의 컨디션이 False 상태일 때, 이에 대한 이유를 알려주는 값들이 존재한다. 파드 안에 있는 컨테이너에도 state라는 각 컨테이너의 상태를 대표하는 값이 있고, state의 세부 내용을 알기 위한 Reason 값이 있다. 컨테이너의 state는 Wating, Running, Terminated와 같은 상태가 있고, Reason에는 각컨테이너 상태에 대한 이유를 알려주는 값들이 있다. Reson에 있는 값들은 각각 ContainerCreating, CrashLoopBackOff, Error, Completed 등이 있다. 

 

① Pending 

 

Pending은 파드의 최초 상태이다. 이 상태일 때, 파드 안에는 init Container라는 본 컨테이너가 기동하기 전에 초기화를 시켜야 하는 내용을 담는 컨테이너가 있다. init Conatainer 안에 있는 초기화 스크립트가 본 컨테이너보다 먼저 실행이 되어 그 작업이 성공적으로 끝났거나 혹은 아예 설정을 하지 않았을 경우 initilaized 의 값은 True가 된다. 만약 실패를 하게 되면 False가 된다.  파드가 어느 노드로 올라갈 지, 직접 지정하였을 경우에는 지정한 해당 노드에 올라가게 되고, 아닐 경우에는 쿠버네티스가 자원의 상황을 판단하여 자동으로 노드를 지정한다. 이 과정이 완료가 되면 PodScheduled 역시 Ture가 된다. 순서는 PodScheduled가 먼저 동작한 후 Initialized를 진행한다. 이후 이미지를 다운 받게 된다. PodScheduled와 initialized가 True가 되기 전 까지 컨테이너의 상태는 waiting 이 되고, Reason값은 Container Creating이다. 

 

 

② Running 

 

본격적으로 컨테이너가 기동되면 파드와 컨테이너의 상태는 Running으로 바뀐다. 일반적으로 정상적으로 기동되지만, 하나 혹은 모든 컨테이너가 기동 중에 문제가 발생하여 재시작 될 수 있다. 이 상황에서 컨테이너의 상태는 waiting이 되고, Reason은 CrashLoopBack 상태가 된다. 파드는 이러한 컨테이너의 상태에 대해서 Runningd으로 간주하지만, 내부 ContainerReady와 Ready는 false값이 된다. 모든 컨테이너들이 정상화 되어 원활하게 돌아간다면 이 값들은 다시 Ture로 변경된다.  일반적으로 서비스를 지속적으로 운영해야 하는 경우, ContainerReady와 Ready의 값을 True로 유지해야 한다. 파드가 Running이어도 안의 컨테이너의 상태는 Running이 아닐 수 있기에 컨테이너의 상태도 모니터링이 필요하다. 또한 Job이나 CronJob으로 생성된 파드는 일을 마치면 파드는 더 이상 일을 하는 상태가 아니게 되는데, 이때 파드의 상태는 Failed와 Succeeded로 나눌 수 있다. 작업중인 컨테이너 중에 하나라도 문제가 생겨 에러가 되면 파드의 상태는 Failed가 되는 것이고, 컨테이너가 모두 Completed로 해야 하는 일을 잘 마쳤을 경우에는 상태가 Succeeded가 된다. 파드의 상태가 Failed이든 Succeeded이든 파드의 Condition 값, 즉 ContainerReady와 Ready은 모두 False로 변하게 된다. 

 

 

+) 추가 

 

Pending 중에 바로 Failed로 빠지는 경우도 있고, pending이나 Running 중에 통신 장애가 발생하면 파드가 Unknown 상태로 변경된다. 이때 장애가 빨리 해결 되면 원래의 상태로 다시 변경되지만 장애가 지속될 경우 상태가 Failed로 변경된다.