Kubernetes 는 객체와 함께 작동한다.
Pods, Deployments Services, Volume …
- 특정 명령을 실행해 이런 객체들을 만들 수 있고 쿠버가 이 객체들을 사용한다.
- 객체에 인코딩된 명령을 기반으로 쿠버가 뭔가 수행함.
- 명령적 방식과 선언적 방식
Pod
쿠버네티스가 상호작용하는 가장 작은 유닛
- 쿠버네티스가 파드를 생성
- 파드는 (하나 이상의)컨테이너 보유하고 실행
- 일반적으로는 하나!
- 쿠버네티스는 파드와 컨테이너 관리
쿠버네티스로 Pod 사용
- 컨테이너 실행 후 클러스터의 특정 워커 노드에서 수행
- 코드 또는 명령을 사용하여 pod 객체 생성
- 객체를 쿠버네티스에게 전송
- 쿠버에게 수행 지시
→ 파드는 컨테이너 생성뿐 아니라 컨테이너 리소스도 공유(볼륨 등)
파드 특징
- 파드도 클러스터의 일부로, 다른 파드나 외부와 통신 가능
- 파드는 디폴트로 클러스터 내부 IP 주소 보유 → 변경 가능
- 클러스터 외부에서도 파드와 통신 가능
- 파드나 파드에서 실행중인 컨테이너에 요청 보내기 가능 !
- 통일한 파드 중 하나에 여러 컨테이너가 있다면 컨테이너는 localhost 주소를 이용해 서로 통신 가능.
- AWS ECS 의 태스크와 쿠버 파드와 비슷함
꿀팁
파드는 임시직이다
- 파드가 쿠버네티스로 교체되거나 제거되면 파드의 모든 리소스(컨테이너로 저장했던 데이터들)들이 손실
- 물론 볼륨처럼 데이터를 유지하는 방법은 있긴 함. 디폴트로는 손실
- 파드는 컨테이너를 둘러싼 작은 래퍼일 뿐임
- 컨테이너랑 개념이 비슷하다.
자체적으로 파드를 만들어 클러스터의 특정 워커 노드에서 시작할 순 있지만, 일반적으론 그렇게 하지 않음.
- 쿠버네티스가 파드를 관리하고 자동으로 생성, 제거, 교체하길 희망함.
- 파드에서 실행중인 애플리케이션이 실패하면 쿠버가 제거하고 교체하고 재생성해야지! 수동으로 하기 싫자나.
Deployment
한 번의 여러 파드를 생성해 내부적으로 컨트롤러 객체를 생성할 수 있다. deployment 객체를 생성하고 관리해야하는 pod 와 컨테이너에 대한 지침을 제공하자.
- 컨테이너가 쿠버네티스에 의해 시작
장점
수동으로 리모트 머신을 선택해서 파드를 배치할 필요 X 쿠버가 해줌
- 쿠버네티스가 파드를 워커 노드에 비치
- 워커노드는 새 파드를 위한 메모리와 CPU 보유!
deployment 롤백 가능
- 애플리케이션에 문제가 생겼을 경우 코드를 변경하고 오류를 수정해야 하는데 급박함..!!
- 하지만 실패한 deployment 를 롤백하고 이전 deployment로 되돌린 뒤
- 버그를 수정 후 업데이트된 컨테이너 이미지로 새 deployment 를 시작하면 끝!
스케일링 가능
- 더 많은 또는 적은 파드를 가지고 싶다고 쿠버에 알리기 가능
- 특정 메트릭을 설정할 수 있는 오토 스케일링 기능
- 메트릭에 수신 트래픽과 CPU 사용률이 있음.
- 메트릭을 초과한 사용률이 있을 경우 쿠버네티스가 자동으로 더 많은 파드 생성 → 요청 처리를 위해 컨테이너 인스턴스 생성
- 트래픽이 저하되면 불필요한 파드 자동 제거
Deployment 를 사용하자
- 직접 pod 를 직접 생성하거나 직접 관리하지 말자.
- 대신 deployment 객체를 사용하여 생성, 이를 쿠버네티스 클러스터에 전송하여 쿠버네티스가 수행하도록 하자.
쿠버네티스는 모두 컨테이너에 관한 것이니 도커는 필요하다! 그냥 자체적으로 컨테이너를 실행한다 vs 쿠버네티스가 관리한다 는 차이가 있을 뿐…
Deployment : 명령적 접근 방식 (실습)
kubectl create 로 명령해서 실행하는
docker build -t kub-first-app .
- 이렇게 빌드한 이미지를 수동으로 쿠버로 보낼 수도 있겠지만…
- pod 의 일부분 또는 Deployment의 일부분으로 pod 를 생성하면…
- 파드에서 실행되는 컨테이너를 제공하고 그걸 관리해줌!
클러스터가 실행 중인지 확인
# 나는 minikube 를 이용해서 더미 클러스터를 사용중이기 때문에
# minikube 가 실행 중인지 확인한당.
minikube status
클러스터에 Deployment 를 생성
kubectl 이라는 큐브 컨트롤 명령으로 수행. 로컬 머신에서 실행하면 됨! ㅎㅅㅎ
### Deployment 생성
kubectl create deployment \\
# 이름
first-app \\
# --image= : deployment 에서 생성된 pod 컨테이너에 사용할 이미지 지정
--image=이미지이름
### 클러스터에 deployment 가 얼마나 있는지 확인
# 참고로 kubectl 은 minikube 에 의해 자동으로 minikube에 연결되도록 구성되어
# minikube 와 상호작용하는지 명시할 필요가 없음.
kubectl get deployments
READY 0/1
- 하나의 deployment 중 하나가 실패함.
### deployment 에서 생성된 모든 것 확인하기
kubectl get pods
STATUS : ImpagePullBackOff
- create deployment 명령으로 생성할 때 클러스터에서 우리가 준 이미지 이름으로 이미지를 찾았으나, 해당 이미지는 우리 로컬 머신에만 있고 클러스터 로컬에서는(클러스터 내에서는) 찾을 수 없음.
해결 방안
- Docker hub 와 같은 이미지 레지스트리에 일부분인 이미지를 지정해야 함.
해결을 하자!
일단 도커 이미지와 deployment 삭제 후 → docker hub 에 레포 만들고 이미지 푸쉬!
docker rmi 이미지
kubectl delete deployment 이름
#도커 허브에 원격 repository 생성 후 ... ###
docker build -t holidaykang/kube-first-app .
docker push holidaykang/kube-first-app
그리고 다시 … deployment 를 생성한다.
# 도커 허브에 있는 파일로 deployment 생성
kubectl create deployment first-app --image=holidaykang/kube-first-
app
# deployment 생성 확인
kubectl get deployments
# pod 생성 확인
kubectl get pods
deployment 확인
pod 확인
- READY 1/1 로 정상 동작 ^ㅅ^/
# 이제까지 생성했던 리소스들을 대쉬보드로 확인 !
minikube dashboard
우와아~~~~~~~^ㅇ^ 신기해!!!!
- 같은 레이블로 디플로이먼트와 파드가 연관되어있음.
kubectl 의 작동 배경
kubectl create deployment --image ...
- deployment 객체를 생성한 다음 자동으로 쿠버네티스 클러스터에 있는 마스터 노드, 즉 컨트롤 플레인으로 전송.
- 마스터 노드의 스케쥴러가 클러스터에 필요한 모든 걸 생성
- deployment 에 저징한 이미지를 기반한 컨테이너, pod 생성 후 워커 노드에 pod 배포
- 이 워커노드에서 kublet 서비스 가능 → pod 관리, 컨테이너 시작, pod 모니터링
Service 객체
파드와 파드에서 실행되는 컨테이너에 접근하기 위해 필요한 객체
파드 내부 IP의 문제점
- 파드 IP는 클러스터 내에서 사용하는 내부 IP에 불과함. 외부에서 접근 불가.
- pod 가 교체될 때마다 변경
서비스가 해주는 일
pod 를 그룹화하고 공유 주소와 공유 IP 를 제공(public IP)
- 서비스를 사용해서 여러 파드를 해당 서비스로 이동시키고 변경 불가한 IP 에 연결 가능
- 이걸로 클러스터 외부에서 pod 에 엑세스 가능!
Service 만들기
# 서비스 생성, deployment 에 의해 생성된 pod 노출하는 명령어
kubectl expose deployment first-app \\
# 내장 유형
# --type=CluesterIP : default, 변경되지 않는 IP 얻을 수 있으나 클러스터 내부에서만 연결할 수 있음.
# --type=NodePort : 해당 deployment 가 실행 중인 워커 노드의 IP 주소로 노출
# 로드밸런서 유형, 서비스 고유 주소 생성하고 들어오는 트래픽을 모든 파드에 고르게 분산.
# 단, 클러스터와 클러스터가 실행되는 인프라가 지원하는 경우에만 사용 가능
--type=LoadBalancer \\
# 포트 노출
--port=8080
내장 유형 종류
ClusterIP
default , 변경되지 않는 IP 얻을 수 있으나 클러스터 내부에서만 연결 가능
NodePort
해당 deployment가 실행 중인 워커 노드의 IP 주소로 노출
LoadBalancer
로드밸런서 유형, 서비스 고유 주소 생성하고 들어오는 트래픽을 모든 파드에 고르게 분산.
→ 단, 클러스터와 클러스터가 실행되는 인프라가 지원하는 경우에만 사용 가능 (minikube, AWS…)
# 서비스들 보기
kubectl get services
- 성공적으로 생성됨!
- kubernetes 는 자동으로 생성된 default service.
EXTERNAL-IP <pending> ?
- 클라우드 프로바이더에 배포되면 실제 외부 IP 를 볼수 있으나, 지금은 minikube 사용중이어서 <pending>
- 왜? minikube 도 결국 로컬에서 실행되는 가상머신일뿐이니까..
- 그래도 minikube 에서 service 엑세스는 가능!
# minikube 로 서비스에 엑세스하기
# minikube 전용이라 클라우드 프로바이더에서는 IP 쓰면 됨!
minikube service 서비스이름
엑세스 성공 ! >.<
- 쿠버네티스 클러스터로 보낸 deployment 기반으로 쿠버네티스가 생성한 pod 에서 실행.
- 쿠버네티스 서비스로 인해서 볼 수 있음 ! !!
알아두기
- 애플리케이션에서 오류가 나서 종료되더라도 deployment 가 컨테이너를 재시작 시켜줌
- 재시작할때마다 다시 시작하는 시간이 길어질 순 있음, 반복 오류가 났을 수도 있어서
스케일링
오토스케일링 설정을 하지 않더라도 직접 스케일링 가능하고 로드밸런서로 트래픽을 분산시켜줌
# 원하는 파드 수를 3개로 지정
kubectl scale deployment/first-app --replicas=3
kubectl get pods 하면, 이렇게 세 개의 파드가 생긴 것을 확인 가능.
- 어느 하나가 멈춰도 다른 곳으로 리디렉션 시켜줌
- 스케일링을 수동으로 하더라도 알아서 트래픽 분산 시켜줌
# 참고로 이렇게 다시 복사본을 1로 축소시키면
kubectl scale deployment/first-app --replicas=1
- 하나만 동작하고 나머진 종료됨. → 저거 두개는 나중에 삭제됨~!
Deployment 업데이트
docker build -t holidaykang/kube-first-app:2 .
docker push holidaykang/kube-first-app:2
- 일단 도커 허브에 새 이미지를 업데이트 해줘야겠지?
- 이 때 기존 컨테이너의 이미지와 태그가 변하면 업데이트하기때문에, 태그를 기존과 다르게 해줌
### 업데이트
# deployment/이름 으로 해당 deployment 를 업데이트해야한다고 알림
kubectl set image deployment/이름 \\
# 이전 이미지 이름=새로운이미지이름 추가 하여, deployment 업데이트
kube-first-app=holidaykang/kube-first-app:2
### 현재 업데이트 상태 확인
kubectl rollout status deployment/이름
# deployment "first-app" successfully rolled out -> 요게 뜨면 제대로 업데이트 됐다는 거!
- minikube dashboard 해보면
- 이렇게 업데이트 된 내역을 확인 가능 ㅎㅅㅎ/
Deployment 롤백 / 히스토리
# 일부러 존재하지 않는 이미지로 이미지 업데이트를 시도한다.
kubectl set image deployment/first-app kube-first-app=holidaykang/kube-first-app:4
# 롤아웃 진행 상황을 검사하면 ?
kuectl rollout status deployment/first-app
- 뭔가 이런 게 뜨면서 deployment 가 완료되기를 기다린다고 뜨며, 실행중인 pod 가 종료..
- 컨트롤 + c 로 일단 빠져나가기
- dashboard 에서는 이미지가 풀링이 안 된다고 에러가 😞
- 안되겠다. 롤백을 해보자 !
# 이전 상태로 롤백
kubectl rollout undo deployment/first-app
- 문제가 있는 파드는 없어지고 다시 이전 상태로 돌아감!
# deployment history 보기
kubectl rollout history deployment/first-app
# 특정 히스토리 정보 보기
kubectl rollout history deployment/first-app --revision=2
# 특정 버전으로 돌아가기
kubectl rollout undo deployment/first-app --to-revision=1
'개발공부 개발새발 > Kubernetes' 카테고리의 다른 글
Kubernetes ) Environment (0) | 2024.04.24 |
---|---|
Kubernetes ) Volume (0) | 2024.04.24 |
Kubernetes ) 선언적 접근 방식으로 쿠버네티스 사용해보기 (0) | 2024.04.22 |
Kubernetes ) 쿠버네티스가 뭐냐~면 (0) | 2024.04.17 |