네트워크교육 32일차 (2022.02.17)

정상훈·2022년 2월 17일
0

잡(JOB)

잡(Job) 컨트롤러는 파드(컨테이너)의 애플리케이션(잡)의 실행이 완료/종료되는 것에 초점을 맞춘 컨트롤러 

레플리케이션 컨트롤러, 레플리카셋, 데몬셋은 파드의 애플리케이션이 계속적으로 잘 동작하는 것을 초점으로 맞춘 것에 대비

즉, 애플리케이션이 실행되고 실행이 완료되면 파드의 할 일이 끝난 것으로 간주하고 파드를 종료

잡 컨트롤러는 임시(Ad-hoc) 작업 및 배치(Batch) 작업에 유용하게 사용될 수 있다.

만약 애플리케이션이 실행되고 있는 중에 노드가 죽거나 파드의 실행이 완료되지 않았다면, 파드를 다시 스케줄링하여 재실행하게 구성할 수 있음

잡 컨트롤러 생성

잡 오프젝트의 API는 batch그룹의 v1버전 사용
오브젝트는 Job

잡 컨트롤러는 레플리케이션 컨트롤러, 레플리카셋, 데몬셋처럼 계속 동작하는 방식x
재시작정책의 Default값을 
Always가 아닌 OnFailure 또는 Never로 명

Job.spec.template.spec.restartPolicy 재시작 정책:
● Always: (기본값) 종료/실패 시 항상 재시작
● Onfailure: 실패 시 재시작 (정상 종료 시 재시작하지 않음)
● Never: 종료 또는 오류 시 절대 재시작 하지 않음

kubectl create -f testapp-job.yaml

잡 컨트롤러 확인

kubectl get jobs.batch
kubectl get pods

잡 컨트롤러 삭제

kubectl delete -f testapp-job.yaml

다중 잡 컨트롤러 생성

job.spec.completions: 작업의 완료 개수 지정

job.spec.completions 필드를 정의해
잡이 한 번으로 완료되지 않고 작업을 여러 번 순차적으로 실행할 수 있음

즉, 하나의 파드가 생성되어 잡이 실행되고 완료되면, 
두 번째 파드가 생성되고 잡이 완료되고,
마지막으로 세 번째 파드가 생성되고 잡이 완료되어야 모든 잡이 완료된 것

다중 잡 컨트롤러 확인

kubectl get jobs.batch
kubectl get pods --watch
kubectl get jobs.batch

다중 잡 컨트롤러 삭제

kubectl delete -f testapp-job-comp.yaml

병렬 다중 잡 컨트롤러 생성

job.spec.parallelism: 동시에 실행할 잡의 개수 지정
job.spec.parallelism 필드를 정의해 병렬로 동시에 실행할 잡의 개수를 지정할 수 있음 

총 세 개의 잡을 실행해야 하며, 동시에 병렬로 세 개의 잡을 실행한다는 의미

kubectl create -f testapp-job-para.yaml

병렬 다중 잡 컨트롤러 삭제

kubectl delete -f testapp-job-para.yaml

크론 잡

잡 컨트롤러는 잡이 한 번만 실행이 되지만 CronJob 컨트롤러는
주기적으로 잡을 반복적으로 실행할 필요가 있을 때 사용하는 컨트롤러

Linux시스템의 Crontab 도구와 기능이 같음

크론 잡 컨트롤러 생성

크론잡 컨트롤러는 아직 베타 기능이며, API역시 batch그룹을 사용,
버전은 v1beta1을 사용하며 
오브젝트 종류는 CronJob

가장 중요한 부분 = 스케줄을 지정하는 필드
cronjob.spec.schedult 필드 사용, 주기적인 시간 구성

kubectl create -f testapp-cj.yaml

크론 잡 컨트롤러 및 파드 확인

kubectl get cronjobs.batch

최초 생성 후 ACTIVE된 잡은 없으며, 마지막으로 동작한 잡(LAST Schedule)도 현재까지 없고,

약 2분의 시간이 흐른 뒤 최초의 잡 실행

kubectl get pods --watch 
-> 2분 지켜보기

서비스(Service)

서비스의 이해

파드는 클러스터 외부의 요청이나 클러스터 내부의 다른 파드의 요청에 응답해야 하고,
파드가 다른 파드에서 제공하는 애플리케이션에 접근하기 위해서는 파드를 찾을 수 있어야 함

쿠버네티스가 아닌 기존의 시스템은 애플리케이션이 동작하는 시스템의 호스트 이름이나 정적 IP를 할당하여 해당 애플리케이션을 찾을 수 있지만, 
쿠버네티스 환경에서는 그렇게 할 수 없음

이유

● 파드는 일회성으로 동작하기 위해 설계되었고 언제든지 제거될 수 있음

● 특정 노드에 파드가 스케줄링 되고 IP 주소가 동적으로 할당되며 클라이언트는 파드의 IP 주소를 미리 예측할 수 없음

● 분산 아키텍처 및 수평 스케일링의 경우 여러 파드가 같은 애플리케이션을 제공하기 때문에 각 파드마다 IP가 존재하고, 
스케일링이 될 때마다 클라이언트가 해당 IP를 알 수 없음 

이를 해결하려면 파드는 단일 고정 IP를 통해서 	서비스를 제공해야 함

서비스

서비스는 쿠버네티스 시스템에서 같은 애플리케이션을 실행하고 있는 컨트롤러의파드 그룹에
단일 네트워크 진입 점을 제공하는 리소스

서비스에 부여된 IP는 해당 서비스가 종료될 때 까지 변경되지 않음

클라이언트는 서비스가 제공하는 IP및 포트를 통해 파드에 접근,
kube-dns(coredns)가 적용되어 있다면 
서비스의 이름에 기반한 고유한 FQDN이 부여

서비스는 레이블 셀렉터를 이용해서 서비스 대상의 파드를 설정,
선택된 파드의 목록은 엔드포인트 리소스로 관리

여러 파드 연결 시 라운드 로빈 방식 

서비스의 종류

● ClusterIP
∙ 클러스터 내부용 서비스

● NodePort
∙ NodePort + ClusterIP 
∙ 쿠버네티스 모든 노드(호스트)에 외부 접근용 포트를 할당함
∙ 노드의 포트를 사용하여 외부에서 접근 가능
∙ 노드의 포트로 접근하면 서비스에 의해 파드로 리다이렉션 함
∙ 파드를 실행하고 있지 않는 노드에도 포트가 할당되고, 접근 가능함

● LoadBalancer
∙ LoadBalancer + NodePort + ClusterIP 
∙ NodePort의 확장
∙ 클러스터 외부의 로드 밸런서를 사용하여 외부에서 접근 가능
∙ 외부 로드 밸런서로 접근하면 서비스를 통해 파드로 리다이렉션 함
∙ 클라우드 공급업체(AWS, GCP 등)나 MetalLB에서 지원

● ExternalName
∙ 외부에서 접근하기 위한 종류 아님
∙ 외부의 특정 FQDN에 대한 CNAME 매핑을 제공
∙ 파드가 CNAME을 이용해 특정 FQDN과 통신하기 위함

서비스 목록 확인

kubectl get services

서비스 리소스와 동일한 이름의 엔드포인트 리소스도 확인

kubectl get endpoints

서비스 및 엔드포인트는 쿠버네티스 아키텍처에서 살펴본
컨트롤 플레인의 API 서버로 접근할 수 있는 서비스로,
클러스터 내부의 파드가 API 서버에 접근하기 위해 해당 서비스를 통해 접근

서비스 생성(명령어)

kubectl expose <CONTROLLER_TYPE> <CONTROLLER_NAME> [--type=<SVC_TYPE>] -- name <SVC_NAME>

서비스 생성 (YAML파일)

.spec.ports.port: 서비스 리소스의 포트

.spec.ports.targetPort: 파드(대상) 리소스의 포트

.spec.selector: 파드 레이블 셀렉터, 엔드포인트 리소스 생성

서비스 오브젝트의 API는 v1을 사용하며 종류는 Service

.spec.ports.port 필드는 클라이언트가 접근할 서비스의 포트이며, 
해당 포트로 접근하면 서비스는 .spec.ports.targetPort 필드에 지정된 파드의 서비스 포트로 포워딩하게 됨

service.spec.selector 필드는 서비스에 연결할 파드를 레이블 셀렉터를 이용하여 매칭하게 되며 
레이블 셀렉터가 있는 경우 서비스 리소스 이름과 똑같은 엔드포인트 리소스가 자동으로 생성

서비스 확인

kubectl get services testapp-svc

서비스 타입은 ClusterIP이며, 
이는 쿠버네티스 클러스터 내에서만 접근할 수 있는 타입

서비스에 할당된 클러스터 IP(CLUSTER-IP)는 10.233.xxx.xxx

클러스터 외부에서 접근할 때는 외부 IP(EXTERNAL-IP)를 사용하며 이는 LoadBalancer 타입의 서비스를 선언 시 할당

즉, ClusterIP 서비스 타입은 클러스터 내부에서만 접근할 수 있는 서비스

엔드포인트 확인

엔드포인트는 서비스의 레이블 셀렉터에 의해 연결된(포워딩 할) 파드의 IP 목록을 엔드포인트 리소스로 관리하고 있음

엔드포인트 이름은 서비스의 이름과 같아야 함   

kubectl get endpoints testapp-svc

현재 app=testapp-rs 레이블을 가진 파드가 없기 때문에 엔드포인트 목록도 가지고 있지 않음 

즉, 서비스의 클러스터 IP로 접속하더라도 포워딩 할 파드가 없음

파드 생성 및 엔드포인트 연결

kubectl create -f testapp-rs.yaml
kubectl get endpoints testapp-svc

파드의 목록과 엔드포인트를 비교

kubectl get pods -o wide

엔드포인트 목록과 파드의 IP가 동일 , 접속확인
kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash

kubectl run 명령을 이용하여 파드를 생성할 수 있으며, 
이는 서비스 접근에만 사용할 임시 파드이기 때문에 
--rm 옵션을 사용해 컨테이너 종료 시 자동으로 삭제됨     

서비스의 세션 어피니티 구성

클라이언트 요청을 매번 똑같은 파드로 연결하고 싶은 경우나 그렇게 해야 할 경우가 있음
예를 들어 세션을 계속 유지하지 위한 이유
이것을 세션 어피니티(Session Affinity)라고 함

세션 어피니티 구성

.spec.sessionAffinity:
● None: (기본) 세션 어피니티 없음
● ClientIP: 클라이언트의 IP를 확인해 같은 파드로 연결됨

.spec.sessionAffinity 필드의 속성 값으로는 
None과 ClientIP 두 가지 종류의 세션 어피니티 구성이 있으며, 
기본 값은 None

세션 어피니티 설정은 ClientIP로 설정하면, 쿠버네티스 클러스터의 프록시(kube-proxy)는 
클라이언트의 IP를 확인하여 매번 같은 파드로 연결해 줌

서비스 생성

kubectl create -f testapp-svc-ses-aff.yaml

kubectl get services testapp-svc-ses-aff

kubectl get endpoints testapp-svc-ses-aff

kubectl run nettool -it --image=ghcr.io/c1t1d0s7/network-multitool --rm bash

bash-5.1# curl http://10.233.5.3

항상 같은 파드에 접근하는 것을 확인할 수 있음
profile
"@____

0개의 댓글