반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 검색 기능 확장
- 롬복 어노테이션
- Java
- @EnableScheduling
- 영속 자료구조
- H-index
- 크론 표현식
- @Data
- 정렬
- 프로그래머스
- 코딩 테스트
- @configuration
- kubenetes
- 전화번호 목록
- 쿠버네티스
- @Setter
- 루씬 인 액션
- 스택/큐
- 알고리즘
- 완주하지 못한 선수
- 고차원 함수
- 기능개발
- 가장 큰 수
- @Getter
- 커링
- 모던 자바 인 액션
- 다리를 지나는 트럭
- 해시
- K번째수
- 스프링 스케쥴러
Archives
- Today
- Total
Today I Learned
[쿠버네티스 인 액션] 4. 레플리케이션과 그 밖의 컨트롤러: 관리되는 파드 배포 (1) 본문
728x90
4장에서 다루는 내용
- 파드의 안정적인 유지
- 동일한 파드의 여러 인스턴스 실행
- 노드 장애 시 자동으로 파드 재스케줄링
- 파드의 수평 스케줄링
- 각 클러스터 노드에서 시스템 수준의 파드 실행
- 배치 잡 실행
- 잡을 주기적 또는 한 번만 실행하도록 스케줄링
4.1 파드를 안정적으로 유지하기
- 애플리케이션에서 특별한 작업을 하지 않더라도 쿠버네티스는 실행중인 애플리케이션에서 크러시가 발생하면 자동으로 재시작한다.
- 하지만 애플리케이션이 무한 루프나 교착 상황에 빠져서 응답을 하지 않는 상황 등 예외 상황이 존재한다. 따라서 애플리케이션 내부 기능에 의존하지 말고 외부에서 애플리케이션의 상태를 체크해야 한다.
4.1.1 라이브니스 프로브 소개
- 라이브니스 프로브(liveness probe)를 통해 컨테이너가 살아있는지 확인할 수 있다.
- 파드의 스펙에 각 컨테이너의 라이브니스 프로브를 지정할 수 있다.
- 프로브의 실행에는 세 가지 메커니즘이 사용된다.
- HTTP GET 프로브는 지정한 IP 주소, 포트, 경로에 HTTP GET 요청을 수행한다. 서버가 오류 응답 코드를 반환하거나 전혀 응답하지 않으면 프로브가 실패한 것으로 간주돼 컨테이너를 다시 시작한다.
- TCP 소켓 프로브는 컨테이너의 지정된 포트에 TCP 연결을 시도해 연결 여부를 확인한다.
- Exec 프로브는 컨테이너 내의 임의의 명령을 실행하고 명령의 종료 상태 코드를 확인한다. 상태 코드가 0이 아니라면 실패로 간주한다.
4.1.2 HTTP 기반 라이브니스 프로브 생성
- 라이브니스 프로브 데모를 위해 다섯 번째 이후의 요청부터는 500 Internal Server Error HTTP 상태 코드를 반환하는 애플리케이션을 만들어보자.
- 그리고 HTTP GET 라이브니스 프로브를 포함된 새 파드를 생성한다.
apiVersion: v1
kind: Pod
metadata:
name: kubia-liveness
spec:
containers:
- image: luksa/kubia-unhealthy #약간의 문제가 있는 애플리케이션을 포함한 이미지
name: kubia
livenessProbe: #라이브니스 프로브
httpGet:
path: /
port: 8080
4.1.3 동작중인 라이브니스 프로브 확인
- kubectl get을 실행해보면 RESTARTS 열에서 파드가 한번 재시작했음을 보여준다.
- 다음 이미지처럼 kubectl describe로 출력되는 내용을 보면 컨테이너가 재시작된 이유를 확인할 수 있다.
- 컨테이너가 현재 실행중이지만 오류로 인해 이전에 종료된 것을 알 수 있다.
- 종료 코드 137은 프로세스가 외부 신호에 의해 종료됐음을 나타낸다. 137은 128+x를 의미하며, x는 프로세스에 전송된 시그널 번호이다. 여기서 x는 SGKILL 시그널번호인 9이다.
- 아래쪽에 나열된 events는 컨테이너가 종료된 이유를 보여준다.
4.1.4 라이브니스 프로브의 추가 속성 설정
- kubectl describe는 라이브니스 프로브에 관한 추가적인 정보도 표시된다는 것을 알 수 있다.
- 명시적으로 지정한 라이브니스 프로브 옵션 외에도 지연(delay), 제한 시간(timeout), 기간(period) 등과 같은 추가 속성을 볼 수 있다. 이런 추가적인 매개변수는 프로브를 정의할 때 지정할 수 있다.
- 컨테이너가 시작된 후 바로 프로브가 시작되고(delay=0s), 1초 안에 응답해야 하며(timeout=1s), 10초마다 프로브를 수행하고(period=10s), 연속 3번 실패하면(failure=3) 재시작된다.
4.1.5 효과적인 라이브니스 프로브 생성
- 운영 환경에서 실행중인 파드는 반드시 라이브니스 프로브를 정의해야한다.
- 프로세스가 실행되는 한 쿠버네티스는 컨테이너가 정상적이라고 간주할 것이다.
라이브니스 프로브가 확인해야 할 사항
- 단순히 서버가 응답하는지를 넘어 특정 URL 경로에 요청하도록 프로브를 구성해 애플리케이션 내에서 실행중인 모든 주요 구성 요소가 살아 있는지 또는 응답이 없는지 확인하도록 구성할 수 있다.
- 라이브니스 프로브는 애플리케이션의 내부만 체크하고, 외부 요인의 영향을 받지 않도록 해야한다.
- 예를 들어 프론트엔드 웹서버의 라이브니스 프로브는 웹서버가 백엔드 데이터베이스에 연결할 수 없을 때 실패를 반환해서는 안된다. 근본적인 원인이 데이터베이스에 있다면 웹서버 컨테이너를 재시작하더라도 문제가 해결되지 않는다.
프로브를 가볍게 유지하기
- 라이브니스 프로브가 너무 많은 연산 리소스를 사용해서는 안되고, 완료하는 데 너무 오래 걸리지 않아야 한다. 기본적으로 1초 내에 완료돼야 한다.
- 프로브의 CPU 사용 시간은 컨테이너의 CPU 시간 할당량으로 계산되므로, 무겁게 만들면 메인 애플리케이션 프로세스가 사용 가능한 리소스가 줄어들게 된다.
프로브에 재시도 루프를 구현하지 마라
- 프로브에 실패 임곗값을 1로 설정하더라도, 쿠버네티스는 실패로 간주하기 전에 프로브를 여러 번 재시도한다. 따라서 프로브에 자체적인 재시도 루프를 구현하는 것은 헛수고이다.
4.2 레플리케이션 컨트롤러 소개
- 레플리케이션 컨트롤러는 파드가 항상 실행되도록 보장하며, 사라진 파드가 감지되면 교체 파드를 생성한다.
- 일반적으로 레플리케이션 컨트롤러는 파드의 여러 복제본(레플리카)을 작성하고 관리한다.
4.2.1 레플리케이션 컨트롤러의 동작
- 레플리케이션 컨트롤러는 실행 중인 파드 목록을 지속적으로 모니터링하고, 파드 수가 의도하는 수와 일치하는지 확인한다.
- 의도하는 파드 수보다 더 많이 생성되는 경우도 있는데 다음과 같은 이유로 발생할 수 있다.
- 누군가 같은 유형의 파드를 수동으로 생성
- 누군가 기존 파드의 유형(type)을 변경
- 누군가 의도하는 파드 수를 줄임
컨트롤러 조정 루프 소개
레플리케이션 컨트롤러의 세 가지 요소 이해
- 레이블 셀렉터(label selector) : 레플리케이션 컨트롤러의 범위에 있는 파드를 결정
- 레플리카 수(replica count) : 실행할 파드의 의도하는 수를 지정
- 파드 템플릿(pod template) : 새로운 파드 레플리카를 만들 때 사용
컨트롤러의 레이블 셀렉터 또는 파드 템플릿 변경의 영향 이해
- 레이블 셀렉터와 파드 템플릿을 변경해도 기존 파드에는 영향을 미치지 않는다.
- 레이블 셀렉터를 변경하면 기존 파드가 레플리케이션 컨트롤러의 범위를 벗어나므로 컨트롤러가 해당 파드에 대한 관리를 중지한다.
- 또한 레플리케이션 컨트롤러는 파드를 생성한 후에는 파드의 실제 콘텐츠(컨테이너 이미지, 환경변수 및 기타사항)에 신경을 쓰지 않는다.
- 따라서 템플릿은 이 레플리케이션 컨트롤러로 새 파드를 생성할 때만 영향을 미친다.
레플리케이션 컨트롤러 사용 시 이점
- 기존 파드가 사라지면 새 파드를 시작해 파드가 항상 실행되도록 한다.
- 클러스터 노드에 장애가 발생하면 장애가 발생한 노드에서 실행중인 모든 파드에 관한 교체 복사본이 생성된다.
- 수동 또는 자동으로 파드를 쉽게 수평으로 확장할 수 있다.
4.2.2 레플리케이션 컨트롤러 생성
- 레플리케이션 컨트롤러를 위한 yaml 파일을 만든다.
apiVersion: v1
kind: ReplicationController
metadata:
name: kubia
spec:
replicas: 3
selector:
app: kubia
template:
metadata:
labels:
app: kubia
spec:
containers:
- name: kubia
image: luksa/kubia
ports:
- containerPort: 8080
$kubectl create -f kubia-rc.yaml
- 레이블 셀렉터 app=kubia와 일치하는 파드 인스턴스가 세 개를 유지하도록 하는 kubia라는 이름의 레플리케이션 컨트롤러를 생성한다.
- 템플릿의 파드 레이블은 레이블 셀렉터와 완전히 일치해야 한다. 그렇지 않으면 새 파드가 무한정 생성될 수 있다. 이 경우를 방지하기 위해 api 서버는 레플리케이션의 정의를 검증하고 잘못된 경우 받아들이지 않는다.
- 셀렉터를 지정하지 않으면 템플릿의 레이블로 자동 설정된다.
4.2.3 레플리케이션 컨트롤러 작동 확인
- 파드를 조회해 레플리케이션 컨트롤러가 해야할 작업을 수행했는지 확인해보자.
삭제된 파드에 관한 레플리케이션 컨트롤러의 반응 확인
- 파드 중 하나를 수동으로 삭제해서, 컨트롤러가 어떻게 새로운 파드를 즉시 기동하는지 확인한다.
- 파드를 다시 조회하면 4개가 표시된다. 이는 삭제한 파드가 종료중(Terminating)이고 새 파드는 이미 생성됐기 때문이다.
레플리케이션 컨트롤러 정보 얻기
- 다음 명령으로 레플리케이션 컨트롤러의 정보를 살펴보자.
$kubectl get rc
- 다음과 같이 kubectl describe 명령을 사용해 추가 정보를 볼 수 있다.
컨트롤러가 새로운 파드를 생성한 원인 정확히 이해하기
- 컨트롤러는 삭제되는 파드에 대해 즉시 통지를 받지만(API 서버는 클라이언트가 리소스 및 리소스 목록의 변경을 감시할 수 있도록 허용한다), 이 통지 자체가 대체 파드를 생성하게 하는 것은 아니다.
- 이 통지는 컨트롤러가 실제 파드 수를 확인하고, 적절한 조치를 취하도록 하는 트리거 역할을 한다.
노드 장애 대응
- 레플리케이션 컨트롤러는 노드의 파드가 다운됐음을 감지하자마자 파드를 대체하기 위해 새로운 파드를 기동한다.
- 실습을 위해 먼저 다음 명령어로 파드가 실행중인 노드들을 확인한다.
$kubectl get pods -o wide
- 다음 명령어를 통해 파드가 실행중인 노드 중 하나에 ssh로 접속한다.
$gcloud compute ssh gke-kubia-pool-1-01349329-nw03
- 그리고 다음 명령어로 네트워크 인터페이스를 종료한다.
$sudo ifconfig eth0 down
- 이제 새로운 터미널에서 노드를 조회하면 노드가 다움된 것을 쿠버네티스가 감지해서 NotReady로 표시된다.
- 지금 파드를 조회하면 쿠버네티스가 파드를 다시 스케줄링하기 전에 잠시 대기하기 때문에(일시적인 네트워크 결함이나 kubelet이 다시 시작하는 이유로 노드에 도달할 수 없는 경우) 이전과 동일하게 세 개의 파드로 계속 표시된다.
- 노드가 몇 분 동안 접속할 수 없는 상태로 유지될 경우 해당 노드에 스케줄된 파드의 상태가 알 수 없음(unknown)으로 변경되고 새로운 파드가 기동된다.
- (그런데 책과는 다르게 실습에서는 Terminating 상태로 변경되었다.)
- 노드를 되돌리려면 다음 명령으로 노드를 재설정해야 한다.
$gcloud compute instances reset gke-kubia-defualt-pool-1-01349329-nw03
- 노드가 다시 부팅되면 노드가 준비(Ready) 상태로 돌아오고, 알 수 없는(unknown) 상태의 파드는 삭제된다.
4.2.4 레플리케이션컨트롤러의 범위 안팎으로 파드 이동하기
- 컨트롤러가 생성한 파드는 컨트롤러와 묶이지 않으며, 컨트롤러는 레이블 셀렉터와 일치하는 파드만을 관리한다.
- 파드의 레이블을 변경하면 컨트롤러의 범위에서 제거되거나 추가될 수 있다.
- 파드의 레이블을 변경해 컨트롤러의 레이블 셀렉터와 일치하지 않게 만들면 파드는 더이상 관리되지 않게되며, 컨트롤러는 사라진 파드를 대체하기 위한 새로운 파드를 기동한다.
- 컨트롤러는 파드에 추가 레이블이 있는지 상관하지 않으며 오직 파드가 레이블 셀렉터에서 참조하는 모든 레이블을 갖고 있는지만 고려한다.
레플리케이션컨트롤러가 관리하는 파드에 레이블 추가
- 관리되는 파드에 레이블을 추가하더라도 레플리케이션컨트롤러가 상관하지 않는지 확인해보자.
$kubectl label pod kubia-dx6x4 type=special
$kubectl get pods --show-labels
- 파드 중 하나에 type=special 라벨을 추가하더라도 컨트롤러와 관련해서 어떤 변경도 발생하지 않았기 때문에 전체 파드를 조회하면 여전히 파드 세 개가 표시된다.
관리되는 파드의 레이블 변경
- 파드가 더이상 컨트롤러의 레이블 셀렉터와 일치하지 않도록 변경해보자.
$kubectl label pod kubia-dx6x4 app=foo --overwrite
- overwrite 인수가 없으면 경고만 표시되고 레이블이 변경되지 않는다.
kubectl get pods -L app
- 전체 파드를 다시 조회해보면 네 개의 파드가 표시된다.
- kubia-dx6x4는 이제 독자적인 파드가 됐으며, 수동으로 삭제할 때까지 계속 실행된다.
컨트롤러에서 파드를 제거하는 실제 사례
- 파드가 오작동하는 것을 발견했다면 레플리케이션컨트롤러의 범위 밖으로 빼내 새 파드로 교체하도록 한 다음, 원하는 방식으로 파드를 디버그하거나 문제를 제연해볼 수 있다. 완료되면 파드를 삭제한다.
레플리케이션컨트롤러의 레이블 셀렉터 변경
- 파드의 레이블은 변경하는 대신 레플리케이션컨트롤러의 레이블 셀렉터를 수정하면 모든 파드가 컨트롤러의 범위를 벗어나므로 세 개의 새로운 파드가 생성된다.
4.2.5 파드 템플릿 변경
- 레플리케이션컨트롤러의 파드 템플릿을 수정하더라도 기존 파드에는 영향을 주지 않으며 새로운 파드에만 적용된다.
- 다음 명령을 사용해 레플리케이션 컨트롤러를 편집할 수 있다.
$kubectl edit rc kubia
- 파드 템플릿 섹션을 찾아 메타데이터에 레이블을 수정하고 신규 파드로 교체되도록 하면 새로운 레이블을 갖는 파드를 볼 수 있다.
4.2.6 수평 파드 스케일링
레플리케이션컨트롤러 스케일 업(확장)하기
- 레플리케이션컨트롤러가 최대 10개의 파드 인스턴스를 유지하도록 조정해보자.
$kubectl scale rc kubia --replicas=10
- 위 명령어를 사용할 수도 있지만 이번에는 다른 방식을 사용한다.
레플리케이션컨트롤러의 정의를 편집해 스케일링하기
- 레플리케이션컨트롤러의 정의를 편집해 선언적인 방식으로 확장할 것이다.
$kubectl edit rc kubia
- 파일을 저장하면 레플리케이션컨트롤러가 업데이트되고, 즉시 파드의 수가 10개로 확장된다.
- kubectl scale 명령이 쿠버네티스에게 무엇을 해야할지 정확히 알려주는 것처럼 보인다면, 이제는 레플리케이션컨트롤러의 의도하는 상태를 선언적으로 변경한다는 것이 훨씬 명확해 보인다.
kubectl scale 명령으로 스케일 다운(축소)하기
- 이제 이전 상태인 세 개로 축소해보자. 이 명령은 kubectl edit을 통해 변경했을 때와 같이 레플리케이션 컨트롤러 정의의 spec.replicas 필드의 값을 수정하는 것이다.
$kubectl scale rc kubia --replicas=3
스케일링에 대한 선언적 접근 방법 이해
- 쿠버네티스에서 파드를 수평으로 확장한다는 것은 쿠버네티스에게 무엇을 하라고 말하는게 아니라 의도하는 상태를 지정할 뿐이다.
- 이 선언적 접근 방식을 통해 쿠버네티스 클러스터와 쉽게 상호작용 할 수 있으며, 명시적인 방식보다 훨씬 적은 작업과 오류 발생율을 가진다.
4.2.7 레플리케이션컨트롤러 삭제
- kubectl delete를 통해 레플리케이션컨트롤러를 삭제하면 파드도 삭제된다. 그러나 컨트롤러만 삭제하고 파드는 실행 상태로 둘 수도 있다.
- 이 작업은 파드에 영향을 주지 않고 수행할 수 있으며 파드를 관리하는 레플리케이션컨트롤러를 교체하는 동안 중단없이 실행할 수 있다.
$kubectl delete rc kubia --cascade=false
728x90
'쿠버네티스' 카테고리의 다른 글
[쿠버네티스 인 액션] 5. 서비스: 클라이언트가 파드를 검색하고 통신을 가능하게 함 (1) (0) | 2022.09.13 |
---|---|
[쿠버네티스 인 액션] 4. 레플리케이션과 그 밖의 컨트롤러: 관리되는 파드 배포 (2) (0) | 2022.08.25 |
[쿠버네티스 인 액션] 3. 파드: 쿠버네티스에서 컨테이너 실행 (2) (0) | 2022.08.12 |
[쿠버네티스 인 액션] 3. 파드: 쿠버네티스에서 컨테이너 실행 (1) (0) | 2022.08.05 |
[쿠버네티스 인 액션] 2. 도커와 쿠버네티스 첫걸음 (3) (0) | 2022.08.01 |
Comments