Kubernetes

둥냥둥냥둥·2024년 1월 11일
0
post-thumbnail

파드와 디플로이먼트로 컨테이너 실행


01. 쿠버네티스는 어떻게 컨테이너를 실행하고 관리하나

컨테이너는 일반적으로 애플리케이션 구성 요소 하나를 실행하는 가상화된 환경을 가리킨다. Kubernetes는 이 컨테이너를 또 다른 가상 환경인 pod로 감싼다.

pod는 컨퓨팅의 단위로, cluster를 다루는 노드 중 하나에서 실행된다. pod는 Kubernetes로 관리되는 자신만의 가상 IP주소를 가지며 이 주소로 가상 네트워크에 접속된 다른 pod, 심지어 다른 노드에서 실행되는 pod라도 통신을 주고받을 수 이다.

pod 하나는 대개 컨테이너 하나를 포함하는데. 설정에 따라 하나가 여러 개의 컨테이너를 포함할 수도 있다. pod에 포함된 모든 컨테이너는 같은 가상 환경에 포함된다. 따라서 네트워크를 공유하면 localhost로 서로 통신할 수도 있다.


01. 실습 : pod를 직접 실행하고 추상화된 컨테이너를 살피자.


1. 컨테이너 하나를 담은 파드를 실행


2. 파드 목록을 출력


3. 특정 파드에 대한 정보 확인



실습결과를 확인해 보자. 컨테이너는 파드 안에 들어 있는 상태다. 도커를 사용해 보았다면 익숙한 과정이였을 것이다. 또한 파드도 그렇게 어렵게 느껴지지 않았을 것이다. 대부분의 파드는 하나의 컨테이너만 실행한다. 따라서 파드를쿠버네티스가 컨테이너를 실행하는 수단으로 생각해도 크게 틀리지 않다.

쿠버네티스가 직접 컨테이너를 실행하지는 않는다. 컨테이너를 생성할 책임을 해당 노드에 설치된 컨테이너 런타임에 맡기는 형태이다. 이 컨테이너 런타임은 도커가 될 수도 있고, 그 외에 더 특이한 것이 될 수도 있다. 파드가 컨테이너를 추상화시킨 것인 이유가 여기에 있다. 파드는 쿠버네티스가 관리하는 소스고, 컨테니어는 쿠버네티스 외부에서 관리된다.


02. 실습 : 파드에 대한 정보확인

1. 파드의 기본정보 확인

kubectl get pod hello-kiamol 

2. 네트워크 상세 정보 중 특정한 항목 출력

kubectl get pod hello-kiamol --output custom-columns=NAME:metadata.name,NODE_OP:status.hostIP,POD_IP:status.podIP

3. jsonpath 복잡한 출력을 구성

kubectl get pod hello-kiamol -o jsonpath='{.status.containerStatuses[0].containerID}'

결과
1 : 단일 노드 쿠버네티스 클러스터를 구동 중이다.
2 : NODE_OP는 리눅스 IP, POD_IP 클러스터 속 pod IP
3 : 도커로 실행된 컨테이너이므로 docker가 붙었다.



실습을 통해서 알아야 할 점이 있다. 첫번째는
kubectl이 매우 강력한 도구인 점이다.
쿠버네티스와의 주요 접점 역할회에도 다양한 용도로 kubectl을 사용하게 될 것이다. kubectl의 기능을 확실히 파악해 두면 도움이 된다. 명령어에 관심 있는 출력 내용에 대한 질의를 지정하는 것도 유용하다. 리소스 정보 중 원하는 벙보에 마음대로 접근할 수 있고, 특히 자동화시킬 대 편리하다.

두번째는 컨테이너를 직접 실행하는 것은 쿠버네티스가 아니라는 점이다. 파드에서 볼 수 있는 컨테이너 식별자는 컨테이너가 실제 실행되는 다른 시스템을 가리키는 참조일 뿐이다.

파드는 파드를 생성할 때 한 노드에 배정된다. 그리고 이 파드를 관리하고 파드에 포함된 컨테이너를 실행하는 책임도 이 노드가 맡는다. 이 과정은 컨테이너 런타임 인터페이스라는 공통 API를 이용하여 컨테이너 런타임과 연동되는 형태로 진행된다. CRL를 사용하면 해당 노드가 어떤 컨테이너 런타임을 실행 중이더라도 같은 방식으로 노드를 관리할 수 있다. 컨테이너 생성과 삭제, 컨테이너 정보 확인 기능이 표준 API로 제공된다. 파드 실행 중에는 노드가 커네이너 런타임과 연동하며, 파드에 필요한 모든 컨테이너가 갖추어져 있는지 확인한다.


02. 컨트롤러 객체와 함께 파드 실행

쿠버네티스 객체, 컨트롤러 객체를 배우게 되었다. 컨트롤러 객체는 다른 객체를 다시 추상화한 것이다. 쿠버네티스가 매우 복잡한 시스템이기는 하지만, 이 복잡성이 바로 강력하고 다양한 설정이 가능한 시스템을 만드는 원동력이다. 학습에 따르는 약간의 어려움은 전 세계적으로 널리 쓰이는 컨테이너 플랫폼에 참여할 수 있는 입장료라고 생각하자.

파드는 직접 사용하기에는 너무 단순한 객체다.
파드는 고립된 한 벌의 애플리케이션이며, 각 파 드는 서로 다른 노드에 배정된다. 어떤 노드가 고장을 일으킨다면 파드는 유실되며, 쿠버네티스는 유실된 파드를 새 파드로 대체하지 않는다. 여러 파드를 실행하며, 고가용성을 확보하려고 해도 모든 파드가 다른 노드에 흩어져서 실행된다는 보장이 없다. 억지로 서로 다른 노드에 실행되도록 사람이 직접 관리해야 한다면 오케스트레이션 도구를 사용하는 의미가 없다.

컨트롤러 객체가 바로 이런 불편함을 해결해 준다.
컨트롤러 객체는 다른 리소스를 관 리하는 쿠버네티스 리소스다. 컨트롤러는 쿠버네티스 API와 연동하며 시스템의 현재 상태를 감시 하다가 '바람직한 상태'와 차이가 생기면 필요에 따라 그 차이를 바로잡는다. 쿠버네티스에는 여러 가지 컨트롤러 객체가 있다. 그중에서도 파드를 주로 관리하는 컨트롤러 객체는 디플로이먼트다.

앞서 설명했던 파드의 문제점을 디플로이먼트가 모두 해결해 준다.
어떤 노드가 고장을 일으켜 파드가 유실되면, 디플로이먼트가 대체 파드를 다른 노드에 실행한다. 디플로이먼트를 스케일링하 고 싶다면 필요한 파드 수를 지정하면 된다. 그러면 디플로이먼트가 여러 노드에 걸쳐 필요한 수 만큼 파드를 실행한다.


03. 실습 : 디플로이먼트 사용해 실행

1. 디플로이먼트로 실행

이제 클러스터애서 파드 두 개가 생겼다.

  • 첫 번째는 run 명령어로 만들었다.
  • 두 번째는 디플로리먼트로 생성했다.
    디플로이먼트가 생성한 파드 이름은 쿠버네티스가 지은 것으로, 디플로이먼트 이름 뒤에 무작위 문자열이 붙는다.


03 실습에서 알아야 할 중요한 점은 우리가 디플로이먼트는 만들었지만 파드를 직접 만든 적은 없다는 것이다. 디플로이먼트를 정의할 때 우리에게 필요한 파드가 어떤 것인지 기술했다. 그러면 디플로이먼트는 쿠버네티스 API를 통해 현재 동작 중인 리소스가 무엇이 있는지 살펴보고, 자신 이 관리해야 할 파드가 없다는 사실을 발견하여 다시 쿠버네티스 API를 통해 자신에게 필요한 파드를 생성한다. 디플로이먼트만 만들면 우리에게 필요한 파드를 대신 만들어 준다는 점이 중요하다.

하지만 디플로이먼트가 자신이 관리해야 할 리소스를 어떻게 추적하는지는 알아 둘 필요가 있다.

이런 패턴은 쿠버네티스 전반에서 매우 많이 쓰인다. 모든 쿠버네티스 리소스는 간단한 키-값 쌍 형태의 레이블을 가지며, 이 레이블을 우리가 원하는 데이터를 담는 데 사용할 수 있다.

예를 들어 디플로이먼트에 release라는 레이블을 추가하고 그 값을 20.04라고 지정한다면, 우리는 나중에 이 디플로이먼트가 배포 주기 20.04에 배포된 것임을 알 수 있다. 또한 레이블은 디플로이먼트와 파드의 관계처럼 객체 간 관계를 표현해서 리소스와 리소스의 느슨한 연결을 만드는 데도 쓰인다.


04. 실습 : kubectl 디플로이먼트 레이블 출력

1. 디플로이먼트의 상세 정보를 확인한다.
디플로이먼트가 파드에 부여한 레이블을 반환하는 질의를 사용



2. 레이블 셀렉터를 사용하여 앞서 확인한 레이블이 일치하는 파드 목록 출력



레이블을 이용하여 리소스 간 관계를파알하는 것은 쿠버네티스에서 매우 자주 쓰는 중요한 패턴이다. 리소스는 생애 주기를 거치며 생성이나 수정, 삭제와 함께 레이블을 부여받는다. 또한 컨트롤러 객체는 레이블 셀렉터를 통해 자신이관리하는 리소스인지 판단한다. 아래의 사진과 같이 리소스가 가진 특정한 레이블이 일치하는지 확인하는 과정이다.

컨트롤러가 자신이 관리하는 리소스 목록을 유지하지 많아도, 레이블 셀렉터가 컨트롤러 객체의 정의에 포함되어 있기 때문에 컨트롤러 객체가 언제라도 쿠버네티스 API를 통해 자신이 관잔하는 리소스를 찾아볼 수 잇다는 점에서 매우 유연한 설계이다. 하지만 레이블 정보를 함부로 직접 수정하면 이런 리소스 간 관계를 흐트러트릴 수 잇기 때문에 주의해야 한다.


05. 실습 : 파드의 레이블 수정

1. 모든 파드 이름과 레이블 확인
2. 디플로이먼트가 생성한 파드의 app 레이블 수정
3. 파드가 또 하나 생성 확인

kubectl get pods -o custom-columns=NAME:metadata.name,LABELS:metadata.labels

kubectl label pods -l app=hello-kiamol-2 --overwrite app=hello-kiamol-x

06. 실습 : 원래대로 수정

1. app 이라는 부여 레이블 출력
2. 원상태로 돌려 주도록 명령어 수정

kubectl get pods -o custom-columns=NAME:metadata.name,LABELS:metadata.labels

kubectl label pods -l app=hello-kiamol-x --overwrite app=hello-kiamol-2

profile
Java 먹자

0개의 댓글