오늘은 레플리카셋에 대해 공부해보고자 한다.
ref: 시작하세요 도커/ 쿠버네티스
레플리카 셋은 일정 개수의 포드를 유지하는 컨트롤러임.
쿠버네티스의 기본 단위인 포드는 여러 개의 컨테이너를 추상화해 하나의 애플리케이션으로 동작하도록 만드는 컨테이너 묶음.
그러나 yaml에 포드만 정의해 생성하면 이 포드의 lifecycle은 오직 쿠버네티스 사용자에 의해서만 관리될 수 있음. (지우거나 만들기를 사용자가 직접)
그러나 실제로 외부 사용자의 요청을 처리해야 하는 마이크로 서비스 구조의 포드라면 이러한 방식을 사용하기 어려움.
왜?
도커 기준으로 마이크로 서비스에서는 여러 개의 동일한 컨테이너를 생성한 뒤 외부 요청이 각 컨테이너에 적절히 분배될 수 있어야 하기 때문에.
그러면 쿠버에서는 기본 단위가 포드이기 때문에 동일한 여러 개의 포드를 생성해 외부 요청을 각 포드에 분배하는 방식을 사용해야 함.
동일한 여러 개의 포드를 생성하는 방법은?
다른 이름을 가진 여러 개의 포드를 직접 만드는 것 : 이 방법은 적합하지 않음.
따라서 레플리카셋을 사용하게 된다.
레플리카 셋이 하는 일
따라서, 동일한 포드를 안정적으로 여러 개 실행할 수도 있고, 워커 노드에 장애가 생기더라도 정해진 개수의 포드를 유지할 수도 있다.
이처럼 레플리카셋이 대신 포드를 관리하기 때문에 직접 관리할 일은 거의 없게 된다.
nginx 포드를 생성하는 레플리카셋 만들기.
yaml파일을 다음과 같이 작성해 준다.
metadata
의 name
항목에서 replicaset-nginx
로 설정이전의 yaml파일과 비교했을 때 추가된 부분
spec.replicas: 동일한 포드를 몇 개 유지시킬 것인지 설정
spec.template ~ : 포드를 생성할 때 사용할 템플릿을 정의한다.
yaml파일에서의 들여쓰기된 항목의 이름을 '.'으로 표현한 것.
포드를 생성했던 방식과 동일하게 kubectl apply -f
명령어로 yml파일을 읽어와 생성함.
kubectl apply -f replicaset-nginx.yaml
kubectl get po
: 포드의 목록 확인하기kubectl get rs
: 레플리카셋의 목록 확인하기3개의 포드가 정상적으로 생성되었고, 레플리카셋도 잘 떠있는 것을 확인할 수 있음.
레플리카셋의 포드 개수를 변경하기 위해 이미 생성된 레플리카셋을 삭제하고 다시 생성할 필요는 없음.
쿠버네티스에서는 이미 생성된 리소스의 속성을 변경하는 기능을 제공.
kubectl edit
, kubectl patch
등 여러 방법을 사용할 수 있지만, 책에서는 yaml 파일의 숫자만 간단히 바꾸는 법을 설명함.
cp해서 변경한 후 다시 적용하니 configured라고 읽힘.
변경된 것을 알 수 있음.
삭제는 마찬가지로 kubectl delete -f
혹은 kubectl delete rs
명령어를 통해 할 수 있음.
앞에서 있는 것만 보면 레플리카셋이 포드와 연결된 것처럼 보임.
레플리카 셋을 생성하면 포드가 생성되고, 레플리카 셋을 삭제하면 포드 또한 삭제되니까.
그러나 실제로 레플리카셋은 포드와 연결되어 있지 않다.
띠용 이게 무슨 🐶소리입니까? 여기서 멘붕 ;ㅅ;
레플리카 셋과 포드는 느슨한 연결(loosely coupled)을 유지하고 있으며, 이러한 느슨한 연결은 포드와 레플리카셋의 정의 중 라벨 셀렉터(Label Selector)를 이용해 이뤄진다.
라벨 셀렉터를 이해하기 위해 아까 작성한 yaml파일을 다시 보자.
여기에서 template
이전까지는 레플리카셋을 정의한 것이고,
그 아래 metadata
부터는 포드를 정의한 부분이라고 앞서 언급했다.
metadata
항목에서는 리소스의 부가적인 정보를 설정할 수 있는데, 부가 정보 중에는 리소스의 고유한 이름뿐만 아니라 주석, 라벨 등도 포함된다.
특히 라벨은 포드 등의 쿠버네티스 리소스를 분류할 때 유용하게 사용할 수 있는 메타데이터임.
라벨은 쿠버네티스 리소스의 부가적인 정보를 표현할 수 있을 뿐만 아니라, 서로 다른 오브젝트가 서로를 찾아야 할 때 사용하기도 한다.
예를 들어 레플리카셋은 spec.selector.matchLabel에 정의된 라벨을 통해 생성해야 하는 포드를 찾을 수 있다. 즉, app: my-nginx-pods-label
라벨을 가지는 포드의 갯수가 replicas 항목에 정의된 숫자인 3개와 일치하지 않으면, 포드를 정의하는 포드 템플릿(template)의 항목의 내용으로 포드를 생성한다.
자세히 설명하자면, 레플리카셋을 처음 생성했을 때는 app: my-nginx-pods-label
라벨을 가지는 포드가 존재하지 않기 때문에 template에 정의된 포드 설정으로 3개의 포드를 생성한다.
그 다음 새롭게 생성된 3개의 포드는 app: my-nginx-pods-label
을 가지고 있기 때문에 레플리카셋은 더 이상 포드를 생성하지 않는다.
만약 그중 하나에 문제가 생긴다면 동일하게 다시 생성해준다는 것으로 이해하면 될듯.
그렇다면 app: my-nginx-pods-label
을 가지는 포드를 미리 생성해 놓은 다음, 위의 레플리카셋을 생성하면 ...? 잘 된다.
책의 예시에는 그중 하나의 포드를 수동으로 삭제했을 때 다른 포드가 자동으로 생성되는 것도 보여줬는데, 한번 시도해 보기로 한다.
5개의 포드가 있는 것을 확인하고
(안지운 포드때문에 -l
옵션으로 label에 해당하는 리소스만을 줄력하게 했음.)
-l
옵션 사용하기
$ kubectl get pods --show-labels
$ kubectl get pods -l app
$ kubectl get pods -l app=my-nginx-pods-label
레플리카셋과 포드의 라벨은 고유한 키-값 쌍이어야 한다. 위의 예시는 이해를 돕기 위한 것일 뿐, 레플리카셋과 동일한 라벨을 가지는 포드를 직접 생성하는 것은 바람직하지 않음.
이번에는 kubectl edit
명령어로 포드 중 하나의 라벨을 삭제해보자.
kubectl edit
명령어는 리소스의 속성을 변경할 수 있도록 텍스트 편집기를 실행하고, 변경 사항을 적용하려면 파일을 저장한 뒤 빠져나오면 된다.
kubectl edit pods [replicaset 이름]
을 사용하면,
이런 포드 하나의 yaml파일이 열리는 듯.
오호 그러면 label이 더이상 보이지 않는 것을 확인할 수 있음.
근데 내가 초창기에 적용했던 yaml파일에는 app:label 파라미터가 들어가 있으므로 레플리카셋은 새로운 포드를 하나 더 생성한다.
위 예시에서 라벨을 삭제한 포드는 레플리카셋의 selector, matchLabel 항목의 값과 더 이상 일치하지 않으므로 레플리카셋에 의해 관리되지 않으며 수동으로 생성한 포드와 같은 의미가 되는 것.
레플리카셋 마지막 파트이다.
이전 버전의 쿠버네티스에서는 레플리카셋이 아닌 레플리케이션 컨트롤러(replication controller)라는 오브젝트를 통해 포드의 개수를 유지했다.
그러나 쿠버 버전이 올라감에 따라 레플리케이션 컨트롤러는 더 이상 사용되지 않으며, 그 대신 레플리카셋이 사용되고 있다.
어쨌든 레플리케이션 컨트롤러와 레플리카셋의 차이점은 "표현식(matchExpression)" 기반의 라벨 셀렉터를 사용할 수 있다는 것.
selector :
matchExpressions:
- key: app
values:
- my-nginx-pods-label
- your-nginx-pods-label
operator: In
template:
이런식으로 정의해두면 라벨의 키값 app, 밸류값 my-nginx-pods-label, your-nginx-pods-label 이렇게 생기게 되고, 따라서 app: my-nginx-pods-label이라는 값을 가지는 포드뿐만 아니라 app: your-nginx-pods-label이라는 라벨을 가지는 포드 또한 레플리카셋의 관리하에 놓이게 된다.
아 걍 라벨 여러개 줄 수 있다는 거구먼 그래
안녕하세요! 현재 쿠버네티스를 공부하고 있는데 ReplicaSet에 대해 좀 더 쉽게 이해할 수 있었어요! 감사합니다.